summaryrefslogtreecommitdiff
path: root/chromium/content/common
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-05-09 14:22:11 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-05-09 15:11:45 +0000
commit2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c (patch)
treee75f511546c5fd1a173e87c1f9fb11d7ac8d1af3 /chromium/content/common
parenta4f3d46271c57e8155ba912df46a05559d14726e (diff)
downloadqtwebengine-chromium-2ddb2d3e14eef3de7dbd0cef553d669b9ac2361c.tar.gz
BASELINE: Update Chromium to 51.0.2704.41
Also adds in all smaller components by reversing logic for exclusion. Change-Id: Ibf90b506e7da088ea2f65dcf23f2b0992c504422 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'chromium/content/common')
-rw-r--r--chromium/content/common/BUILD.gn176
-rw-r--r--chromium/content/common/DEPS9
-rw-r--r--chromium/content/common/OWNERS13
-rw-r--r--chromium/content/common/accelerated_surface_buffers_swapped_params_mac.cc14
-rw-r--r--chromium/content/common/accelerated_surface_buffers_swapped_params_mac.h28
-rw-r--r--chromium/content/common/accessibility_messages.h21
-rw-r--r--chromium/content/common/android/address_parser_internal.cc2
-rw-r--r--chromium/content/common/android/address_parser_internal.h1
-rw-r--r--chromium/content/common/android/media_metadata_android.cc33
-rw-r--r--chromium/content/common/android/media_metadata_android.h29
-rw-r--r--chromium/content/common/android/surface_texture_manager.cc28
-rw-r--r--chromium/content/common/android/surface_texture_manager.h42
-rw-r--r--chromium/content/common/android/surface_texture_peer.cc33
-rw-r--r--chromium/content/common/android/surface_texture_peer.h38
-rw-r--r--chromium/content/common/android/sync_compositor_messages.cc5
-rw-r--r--chromium/content/common/android/sync_compositor_messages.h33
-rw-r--r--chromium/content/common/appcache_interfaces.cc5
-rw-r--r--chromium/content/common/appcache_interfaces.h1
-rw-r--r--chromium/content/common/appcache_messages.h1
-rw-r--r--chromium/content/common/application_setup.mojom9
-rw-r--r--chromium/content/common/ax_content_node_data.cc2
-rw-r--r--chromium/content/common/ax_content_node_data.h1
-rw-r--r--chromium/content/common/background_sync_service.mojom30
-rw-r--r--chromium/content/common/bluetooth/bluetooth_messages.h59
-rw-r--r--chromium/content/common/bluetooth/bluetooth_scan_filter.cc3
-rw-r--r--chromium/content/common/bluetooth/bluetooth_scan_filter.h1
-rw-r--r--chromium/content/common/browser_plugin/browser_plugin_messages.h23
-rw-r--r--chromium/content/common/buffer_presented_params_mac.cc13
-rw-r--r--chromium/content/common/buffer_presented_params_mac.h23
-rw-r--r--chromium/content/common/cache_storage/cache_storage_messages.h12
-rw-r--r--chromium/content/common/cache_storage/cache_storage_types.cc3
-rw-r--r--chromium/content/common/cache_storage/cache_storage_types.h5
-rw-r--r--chromium/content/common/cc_messages.cc124
-rw-r--r--chromium/content/common/cc_messages.h73
-rw-r--r--chromium/content/common/cc_messages_unittest.cc12
-rw-r--r--chromium/content/common/child_process_host_impl.cc22
-rw-r--r--chromium/content/common/child_process_messages.h57
-rw-r--r--chromium/content/common/child_process_sandbox_support_impl_linux.h5
-rw-r--r--chromium/content/common/clipboard_messages.h5
-rw-r--r--chromium/content/common/common.sb7
-rw-r--r--chromium/content/common/common_param_traits_unittest.cc63
-rw-r--r--chromium/content/common/content_constants_internal.cc5
-rw-r--r--chromium/content/common/content_constants_internal.h7
-rw-r--r--chromium/content/common/content_message_generator.h7
-rw-r--r--chromium/content/common/content_param_traits.cc5
-rw-r--r--chromium/content/common/content_param_traits.h14
-rw-r--r--chromium/content/common/content_param_traits_macros.h3
-rw-r--r--chromium/content/common/content_switches_internal.cc37
-rw-r--r--chromium/content/common/content_switches_internal.h6
-rw-r--r--chromium/content/common/database_identifier_unittest.cc38
-rw-r--r--chromium/content/common/devtools_messages.h14
-rw-r--r--chromium/content/common/discardable_shared_memory_heap.cc4
-rw-r--r--chromium/content/common/dom_storage/dom_storage_messages.h2
-rw-r--r--chromium/content/common/drag_messages.h1
-rw-r--r--chromium/content/common/dwrite_font_platform_win.cc1282
-rw-r--r--chromium/content/common/dwrite_font_platform_win_unittest.cc71
-rw-r--r--chromium/content/common/establish_channel_params.cc18
-rw-r--r--chromium/content/common/establish_channel_params.h27
-rw-r--r--chromium/content/common/experiments/api_key.cc144
-rw-r--r--chromium/content/common/experiments/api_key.h95
-rw-r--r--chromium/content/common/experiments/api_key_unittest.cc191
-rw-r--r--chromium/content/common/fileapi/webblob_messages.h80
-rw-r--r--chromium/content/common/font_config_ipc_linux.cc16
-rw-r--r--chromium/content/common/font_config_ipc_linux.h16
-rw-r--r--chromium/content/common/font_list_win.cc2
-rw-r--r--chromium/content/common/font_warmup_win.cc526
-rw-r--r--chromium/content/common/font_warmup_win.h76
-rw-r--r--chromium/content/common/font_warmup_win_unittest.cc435
-rw-r--r--chromium/content/common/frame_message_enums.h6
-rw-r--r--chromium/content/common/frame_messages.h225
-rw-r--r--chromium/content/common/frame_param.cc40
-rw-r--r--chromium/content/common/frame_param.h10
-rw-r--r--chromium/content/common/frame_param_macros.h60
-rw-r--r--chromium/content/common/frame_replication_state.cc15
-rw-r--r--chromium/content/common/frame_replication_state.h45
-rw-r--r--chromium/content/common/gamepad_param_traits.cc6
-rw-r--r--chromium/content/common/gamepad_param_traits.h5
-rw-r--r--chromium/content/common/geolocation_service.mojom20
-rw-r--r--chromium/content/common/gpu/DEPS3
-rw-r--r--chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.h56
-rw-r--r--chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.mm287
-rw-r--r--chromium/content/common/gpu/ca_layer_tree_mac.h190
-rw-r--r--chromium/content/common/gpu/ca_layer_tree_mac.mm455
-rw-r--r--chromium/content/common/gpu/child_window_surface_win.cc214
-rw-r--r--chromium/content/common/gpu/child_window_surface_win.h45
-rw-r--r--chromium/content/common/gpu/client/DEPS7
-rw-r--r--chromium/content/common/gpu/client/command_buffer_metrics.cc6
-rw-r--r--chromium/content/common/gpu/client/command_buffer_metrics.h2
-rw-r--r--chromium/content/common/gpu/client/command_buffer_proxy_impl.cc820
-rw-r--r--chromium/content/common/gpu/client/command_buffer_proxy_impl.h279
-rw-r--r--chromium/content/common/gpu/client/context_provider_command_buffer.cc63
-rw-r--r--chromium/content/common/gpu/client/context_provider_command_buffer.h12
-rw-r--r--chromium/content/common/gpu/client/gl_helper.cc1391
-rw-r--r--chromium/content/common/gpu/client/gl_helper.h382
-rw-r--r--chromium/content/common/gpu/client/gl_helper_benchmark.cc310
-rw-r--r--chromium/content/common/gpu/client/gl_helper_readback_support.cc183
-rw-r--r--chromium/content/common/gpu/client/gl_helper_readback_support.h72
-rw-r--r--chromium/content/common/gpu/client/gl_helper_scaling.cc934
-rw-r--r--chromium/content/common/gpu/client/gl_helper_scaling.h213
-rw-r--r--chromium/content/common/gpu/client/gl_helper_unittest.cc2016
-rw-r--r--chromium/content/common/gpu/client/gpu_channel_host.cc552
-rw-r--r--chromium/content/common/gpu/client/gpu_channel_host.h318
-rw-r--r--chromium/content/common/gpu/client/gpu_context_tests.h72
-rw-r--r--chromium/content/common/gpu/client/gpu_in_process_context_tests.cc42
-rw-r--r--chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc204
-rw-r--r--chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h73
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl.cc94
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl.h68
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc125
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h63
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc16
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc112
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h63
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc16
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc224
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h77
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc40
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc151
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h60
-rw-r--r--chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc8
-rw-r--r--chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc292
-rw-r--r--chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.h106
-rw-r--r--chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc323
-rw-r--r--chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h131
-rw-r--r--chromium/content/common/gpu/client/grcontext_for_gles2_interface.cc62
-rw-r--r--chromium/content/common/gpu/client/grcontext_for_gles2_interface.h42
-rw-r--r--chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.cc108
-rw-r--r--chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.h66
-rw-r--r--chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc126
-rw-r--r--chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h53
-rw-r--r--chromium/content/common/gpu/gpu_channel.cc1086
-rw-r--r--chromium/content/common/gpu/gpu_channel.h485
-rw-r--r--chromium/content/common/gpu/gpu_channel_manager.cc380
-rw-r--r--chromium/content/common/gpu/gpu_channel_manager.h227
-rw-r--r--chromium/content/common/gpu/gpu_channel_manager_unittest.cc120
-rw-r--r--chromium/content/common/gpu/gpu_channel_test_common.cc112
-rw-r--r--chromium/content/common/gpu/gpu_channel_test_common.h93
-rw-r--r--chromium/content/common/gpu/gpu_channel_unittest.cc329
-rw-r--r--chromium/content/common/gpu/gpu_command_buffer_stub.cc1269
-rw-r--r--chromium/content/common/gpu/gpu_command_buffer_stub.h307
-rw-r--r--chromium/content/common/gpu/gpu_config.h12
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory.cc53
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory.h71
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc121
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.h80
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc16
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc139
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h70
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc20
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc124
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h75
-rw-r--r--chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc16
-rw-r--r--chromium/content/common/gpu/gpu_memory_manager.cc124
-rw-r--r--chromium/content/common/gpu/gpu_memory_manager.h78
-rw-r--r--chromium/content/common/gpu/gpu_memory_tracking.cc37
-rw-r--r--chromium/content/common/gpu/gpu_memory_tracking.h53
-rw-r--r--chromium/content/common/gpu/gpu_memory_uma_stats.h33
-rw-r--r--chromium/content/common/gpu/gpu_messages.h878
-rw-r--r--chromium/content/common/gpu/gpu_result_codes.h20
-rw-r--r--chromium/content/common/gpu/gpu_stream_priority.h20
-rw-r--r--chromium/content/common/gpu/gpu_surface_lookup.cc33
-rw-r--r--chromium/content/common/gpu/gpu_surface_lookup.h40
-rw-r--r--chromium/content/common/gpu/gpu_watchdog.h28
-rw-r--r--chromium/content/common/gpu/image_transport_surface.cc302
-rw-r--r--chromium/content/common/gpu/image_transport_surface.h224
-rw-r--r--chromium/content/common/gpu/image_transport_surface_android.cc42
-rw-r--r--chromium/content/common/gpu/image_transport_surface_linux.cc28
-rw-r--r--chromium/content/common/gpu/image_transport_surface_mac.mm82
-rw-r--r--chromium/content/common/gpu/image_transport_surface_overlay_mac.h148
-rw-r--r--chromium/content/common/gpu/image_transport_surface_overlay_mac.mm522
-rw-r--r--chromium/content/common/gpu/image_transport_surface_win.cc53
-rw-r--r--chromium/content/common/gpu/media/OWNERS13
-rw-r--r--chromium/content/common/gpu/media/android_copying_backing_strategy.cc113
-rw-r--r--chromium/content/common/gpu/media/android_copying_backing_strategy.h10
-rw-r--r--chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc329
-rw-r--r--chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.h40
-rw-r--r--chromium/content/common/gpu/media/android_video_decode_accelerator.cc897
-rw-r--r--chromium/content/common/gpu/media/android_video_decode_accelerator.h206
-rw-r--r--chromium/content/common/gpu/media/android_video_decode_accelerator_unittest.cc23
-rw-r--r--chromium/content/common/gpu/media/android_video_encode_accelerator.cc86
-rw-r--r--chromium/content/common/gpu/media/android_video_encode_accelerator.h9
-rw-r--r--chromium/content/common/gpu/media/avda_codec_image.cc154
-rw-r--r--chromium/content/common/gpu/media/avda_codec_image.h60
-rw-r--r--chromium/content/common/gpu/media/avda_shared_state.cc14
-rw-r--r--chromium/content/common/gpu/media/avda_shared_state.h11
-rw-r--r--chromium/content/common/gpu/media/avda_state_provider.h3
-rw-r--r--chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.cc1017
-rw-r--r--chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.h118
-rw-r--r--chromium/content/common/gpu/media/fake_video_decode_accelerator.cc35
-rw-r--r--chromium/content/common/gpu/media/fake_video_decode_accelerator.h14
-rw-r--r--chromium/content/common/gpu/media/gpu_arc_video_service.cc92
-rw-r--r--chromium/content/common/gpu/media/gpu_arc_video_service.h68
-rw-r--r--chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc56
-rw-r--r--chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.h12
-rw-r--r--chromium/content/common/gpu/media/gpu_video_accelerator_util.cc155
-rw-r--r--chromium/content/common/gpu/media/gpu_video_accelerator_util.h63
-rw-r--r--chromium/content/common/gpu/media/gpu_video_decode_accelerator.cc446
-rw-r--r--chromium/content/common/gpu/media/gpu_video_decode_accelerator.h71
-rw-r--r--chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc242
-rw-r--r--chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h123
-rw-r--r--chromium/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h59
-rw-r--r--chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc207
-rw-r--r--chromium/content/common/gpu/media/gpu_video_encode_accelerator.h41
-rw-r--r--chromium/content/common/gpu/media/media_channel.cc145
-rw-r--r--chromium/content/common/gpu/media/media_channel.h57
-rw-r--r--chromium/content/common/gpu/media/media_service.cc40
-rw-r--r--chromium/content/common/gpu/media/media_service.h42
-rw-r--r--chromium/content/common/gpu/media/rendering_helper.cc14
-rw-r--r--chromium/content/common/gpu/media/rendering_helper.h7
-rw-r--r--chromium/content/common/gpu/media/shared_memory_region.cc42
-rw-r--r--chromium/content/common/gpu/media/shared_memory_region.h57
-rw-r--r--chromium/content/common/gpu/media/v4l2_image_processor.cc30
-rw-r--r--chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc45
-rw-r--r--chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h11
-rw-r--r--chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc98
-rw-r--r--chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h29
-rw-r--r--chromium/content/common/gpu/media/v4l2_video_decode_accelerator.cc202
-rw-r--r--chromium/content/common/gpu/media/v4l2_video_decode_accelerator.h31
-rw-r--r--chromium/content/common/gpu/media/v4l2_video_encode_accelerator.cc103
-rw-r--r--chromium/content/common/gpu/media/vaapi_drm_picture.cc8
-rw-r--r--chromium/content/common/gpu/media/vaapi_drm_picture.h5
-rw-r--r--chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc39
-rw-r--r--chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h9
-rw-r--r--chromium/content/common/gpu/media/vaapi_picture.cc6
-rw-r--r--chromium/content/common/gpu/media/vaapi_picture.h6
-rw-r--r--chromium/content/common/gpu/media/vaapi_tfp_picture.cc8
-rw-r--r--chromium/content/common/gpu/media/vaapi_tfp_picture.h5
-rw-r--r--chromium/content/common/gpu/media/vaapi_video_decode_accelerator.cc63
-rw-r--r--chromium/content/common/gpu/media/vaapi_video_decode_accelerator.h30
-rw-r--r--chromium/content/common/gpu/media/vaapi_video_encode_accelerator.cc40
-rw-r--r--chromium/content/common/gpu/media/vaapi_wrapper.cc24
-rw-r--r--chromium/content/common/gpu/media/vaapi_wrapper.h2
-rw-r--r--chromium/content/common/gpu/media/video_decode_accelerator_unittest.cc187
-rw-r--r--chromium/content/common/gpu/media/video_encode_accelerator_unittest.cc58
-rw-r--r--chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.cc135
-rw-r--r--chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.h19
-rw-r--r--chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.cc552
-rw-r--r--chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.h142
-rw-r--r--chromium/content/common/gpu/stream_texture_android.cc386
-rw-r--r--chromium/content/common/gpu/stream_texture_android.h110
-rw-r--r--chromium/content/common/gpu/x_util.h40
-rw-r--r--chromium/content/common/gpu_host_messages.h300
-rw-r--r--chromium/content/common/gpu_process_launch_causes.h (renamed from chromium/content/common/gpu/gpu_process_launch_causes.h)8
-rw-r--r--chromium/content/common/host_discardable_shared_memory_manager.cc8
-rw-r--r--chromium/content/common/host_discardable_shared_memory_manager.h1
-rw-r--r--chromium/content/common/host_shared_bitmap_manager.cc5
-rw-r--r--chromium/content/common/id_type.h112
-rw-r--r--chromium/content/common/id_type_unittest.cc205
-rw-r--r--chromium/content/common/image_downloader/image_downloader.mojom23
-rw-r--r--chromium/content/common/in_process_child_thread_params.cc9
-rw-r--r--chromium/content/common/in_process_child_thread_params.h7
-rw-r--r--chromium/content/common/indexed_db/indexed_db_messages.h17
-rw-r--r--chromium/content/common/indexed_db/indexed_db_param_traits.cc14
-rw-r--r--chromium/content/common/indexed_db/indexed_db_param_traits.h18
-rw-r--r--chromium/content/common/input/event_with_latency_info.h63
-rw-r--r--chromium/content/common/input/event_with_latency_info_unittest.cc122
-rw-r--r--chromium/content/common/input/input_event_ack_state.h3
-rw-r--r--chromium/content/common/input/input_event_dispatch_type.h26
-rw-r--r--chromium/content/common/input/input_event_utils.cc17
-rw-r--r--chromium/content/common/input/input_event_utils.h17
-rw-r--r--chromium/content/common/input/input_param_traits.cc24
-rw-r--r--chromium/content/common/input/input_param_traits.h12
-rw-r--r--chromium/content/common/input/input_param_traits_unittest.cc60
-rw-r--r--chromium/content/common/input/synthetic_gesture_params.h4
-rw-r--r--chromium/content/common/input/synthetic_pointer_action_params.cc48
-rw-r--r--chromium/content/common/input/synthetic_pointer_action_params.h86
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.cc17
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.h8
-rw-r--r--chromium/content/common/input/web_input_event_queue.h79
-rw-r--r--chromium/content/common/input/web_input_event_traits.cc45
-rw-r--r--chromium/content/common/input/web_input_event_traits.h2
-rw-r--r--chromium/content/common/input/web_input_event_traits_unittest.cc28
-rw-r--r--chromium/content/common/input/web_touch_event_traits.cc4
-rw-r--r--chromium/content/common/input_messages.h27
-rw-r--r--chromium/content/common/leveldb_wrapper.mojom51
-rw-r--r--chromium/content/common/mac/attributed_string_coder.h17
-rw-r--r--chromium/content/common/mac/attributed_string_coder.mm10
-rw-r--r--chromium/content/common/media/OWNERS6
-rw-r--r--chromium/content/common/media/audio_messages.h1
-rw-r--r--chromium/content/common/media/media_param_traits.cc9
-rw-r--r--chromium/content/common/media/media_param_traits.h12
-rw-r--r--chromium/content/common/media/media_player_delegate_messages.h51
-rw-r--r--chromium/content/common/media/media_player_messages_android.h8
-rw-r--r--chromium/content/common/media/media_session_messages_android.h11
-rw-r--r--chromium/content/common/media/media_stream_options.cc2
-rw-r--r--chromium/content/common/media/media_stream_options.h1
-rw-r--r--chromium/content/common/media/surface_view_manager_messages_android.h26
-rw-r--r--chromium/content/common/media/video_capture_messages.h6
-rw-r--r--chromium/content/common/memory_benchmark_messages.h15
-rw-r--r--chromium/content/common/message_router.cc57
-rw-r--r--chromium/content/common/message_router.h71
-rw-r--r--chromium/content/common/mojo/DEPS5
-rw-r--r--chromium/content/common/mojo/channel_init.cc46
-rw-r--r--chromium/content/common/mojo/channel_init.h26
-rw-r--r--chromium/content/common/mojo/current_thread_loader.cc25
-rw-r--r--chromium/content/common/mojo/current_thread_loader.h46
-rw-r--r--chromium/content/common/mojo/mojo_messages.h5
-rw-r--r--chromium/content/common/mojo/mojo_shell_connection_impl.cc120
-rw-r--r--chromium/content/common/mojo/mojo_shell_connection_impl.h56
-rw-r--r--chromium/content/common/mojo/service_registry_impl.cc35
-rw-r--r--chromium/content/common/mojo/service_registry_impl.h33
-rw-r--r--chromium/content/common/mojo/static_loader.cc93
-rw-r--r--chromium/content/common/mojo/static_loader.h66
-rw-r--r--chromium/content/common/navigation_params.cc41
-rw-r--r--chromium/content/common/navigation_params.h20
-rw-r--r--chromium/content/common/net/url_request_service_worker_data.cc17
-rw-r--r--chromium/content/common/net/url_request_service_worker_data.h28
-rw-r--r--chromium/content/common/notification_constants.h12
-rw-r--r--chromium/content/common/one_writer_seqlock_unittest.cc8
-rw-r--r--chromium/content/common/origin_trials/trial_token.cc193
-rw-r--r--chromium/content/common/origin_trials/trial_token.h90
-rw-r--r--chromium/content/common/origin_trials/trial_token_unittest.cc300
-rw-r--r--chromium/content/common/origin_trials/trial_token_validator.cc30
-rw-r--r--chromium/content/common/origin_trials/trial_token_validator.h26
-rw-r--r--chromium/content/common/origin_trials/trial_token_validator_unittest.cc160
-rw-r--r--chromium/content/common/origin_util.cc2
-rw-r--r--chromium/content/common/p2p_messages.h5
-rw-r--r--chromium/content/common/page_messages.h25
-rw-r--r--chromium/content/common/page_state_serialization.cc6
-rw-r--r--chromium/content/common/page_state_serialization.h1
-rw-r--r--chromium/content/common/pepper_plugin_list.cc13
-rw-r--r--chromium/content/common/permission_service.mojom42
-rw-r--r--chromium/content/common/platform_notification_messages.h42
-rw-r--r--chromium/content/common/plugin_constants_win.cc29
-rw-r--r--chromium/content/common/plugin_constants_win.h52
-rw-r--r--chromium/content/common/plugin_list.cc160
-rw-r--r--chromium/content/common/plugin_list.h72
-rw-r--r--chromium/content/common/plugin_list_mac.mm307
-rw-r--r--chromium/content/common/plugin_list_posix.cc37
-rw-r--r--chromium/content/common/plugin_list_unittest.cc8
-rw-r--r--chromium/content/common/plugin_list_win.cc493
-rw-r--r--chromium/content/common/plugin_process_messages.h87
-rw-r--r--chromium/content/common/presentation/presentation_service.mojom14
-rw-r--r--chromium/content/common/process_control.mojom7
-rw-r--r--chromium/content/common/process_type.cc2
-rw-r--r--chromium/content/common/push_messaging_messages.h13
-rw-r--r--chromium/content/common/render_frame_setup.mojom11
-rw-r--r--chromium/content/common/resize_params.cc20
-rw-r--r--chromium/content/common/resize_params.h58
-rw-r--r--chromium/content/common/resource_messages.cc31
-rw-r--r--chromium/content/common/resource_messages.h55
-rw-r--r--chromium/content/common/sandbox_init_mac.cc11
-rw-r--r--chromium/content/common/sandbox_init_win.cc15
-rw-r--r--chromium/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc85
-rw-r--r--chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc23
-rw-r--r--chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc3
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_linux.h2
-rw-r--r--chromium/content/common/sandbox_mac.h3
-rw-r--r--chromium/content/common/sandbox_mac.mm87
-rw-r--r--chromium/content/common/sandbox_mac_diraccess_unittest.mm1
-rw-r--r--chromium/content/common/sandbox_mac_system_access_unittest.mm11
-rw-r--r--chromium/content/common/sandbox_util.cc26
-rw-r--r--chromium/content/common/sandbox_win.cc66
-rw-r--r--chromium/content/common/service_port_service.mojom37
-rw-r--r--chromium/content/common/service_port_type_converters.cc32
-rw-r--r--chromium/content/common/service_port_type_converters.h31
-rw-r--r--chromium/content/common/service_worker/embedded_worker_messages.h15
-rw-r--r--chromium/content/common/service_worker/embedded_worker_settings.h19
-rw-r--r--chromium/content/common/service_worker/embedded_worker_setup.mojom11
-rw-r--r--chromium/content/common/service_worker/service_worker_client_info.cc23
-rw-r--r--chromium/content/common/service_worker/service_worker_client_info.h6
-rw-r--r--chromium/content/common/service_worker/service_worker_messages.h94
-rw-r--r--chromium/content/common/service_worker/service_worker_status_code.h51
-rw-r--r--chromium/content/common/service_worker/service_worker_type_converters.cc10
-rw-r--r--chromium/content/common/service_worker/service_worker_type_converters.h4
-rw-r--r--chromium/content/common/service_worker/service_worker_types.cc40
-rw-r--r--chromium/content/common/service_worker/service_worker_types.h39
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.cc20
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.h4
-rw-r--r--chromium/content/common/service_worker/service_worker_utils_unittest.cc2
-rw-r--r--chromium/content/common/site_isolation_policy.cc23
-rw-r--r--chromium/content/common/site_isolation_policy.h15
-rw-r--r--chromium/content/common/storage_partition_service.mojom15
-rw-r--r--chromium/content/common/swapped_out_messages.cc7
-rw-r--r--chromium/content/common/text_input_client_messages.h2
-rw-r--r--chromium/content/common/url_schemes.cc34
-rw-r--r--chromium/content/common/url_schemes.h12
-rw-r--r--chromium/content/common/utility_messages.h32
-rw-r--r--chromium/content/common/view_messages.h188
-rw-r--r--chromium/content/common/vr_service.mojom2
-rw-r--r--chromium/content/common/wake_lock_service.mojom2
-rw-r--r--chromium/content/common/webplugin_geometry.cc27
-rw-r--r--chromium/content/common/webplugin_geometry.h46
-rw-r--r--chromium/content/common/websocket_messages.h30
-rw-r--r--chromium/content/common/worker_messages.h11
385 files changed, 9400 insertions, 28472 deletions
diff --git a/chromium/content/common/BUILD.gn b/chromium/content/common/BUILD.gn
index 0a7e72e321d..cc769b07c45 100644
--- a/chromium/content/common/BUILD.gn
+++ b/chromium/content/common/BUILD.gn
@@ -126,21 +126,16 @@ if (is_mac) {
}
source_set("common") {
- # Only the public target should depend on this. All other targets (even
- # internal content ones) should depend on the public one.
- visibility = [ "//content/public/common:common_sources" ]
+ # Targets external to content should always link to the public API.
+ # In addition, targets outside of the content component (shell and tests)
+ # must not link to this because it will duplicate the code in the component
+ # build.
+ visibility = [ "//content/*" ]
sources = rebase_path(content_common_gypi_values.private_common_sources,
".",
"//content")
- # These files are only built in a GN build because they bring in
- # dependencies that don't build with GYP.
- sources += [
- "mojo/mojo_shell_connection_impl.cc",
- "mojo/mojo_shell_connection_impl.h",
- ]
-
configs += [
"//content:content_implementation",
"//build/config:precompiled_headers",
@@ -148,69 +143,77 @@ source_set("common") {
]
public_deps = [
+ ":mojo_bindings",
"//gpu/command_buffer/common",
"//ipc",
"//third_party/WebKit/public:blink_headers",
]
deps = [
"//base",
+ "//base/third_party/dynamic_annotations",
"//build/util:webkit_version",
+ "//cc",
+ "//cc/blink",
+ "//cc/surfaces",
"//components/mus/public/interfaces",
"//components/tracing",
"//components/tracing:startup_tracing",
+ "//device/bluetooth",
+
+ # TODO: the dependency on gl_in_process_context should be decoupled from
+ # content and moved to android_webview. See crbug.com/365797.
+ "//gpu",
+ "//gpu/blink",
+ "//gpu/command_buffer/client:gl_in_process_context",
+ "//gpu/command_buffer/client:gles2_c_lib",
+ "//gpu/command_buffer/client:gles2_cmd_helper",
+ "//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/client:gles2_interface",
"//gpu/command_buffer/common:gles2_utils",
- "//mojo/converters/network",
- "//mojo/runner/child:lib",
+ "//gpu/command_buffer/service",
+ "//gpu/ipc/client",
+ "//gpu/ipc/common",
+
+ # TODO(markdittmer): This should be removed once content/common/gpu/media
+ # is refactored into media/ipc.
+ "//gpu/ipc/service",
+ "//gpu/skia_bindings",
+ "//ipc",
+ "//ipc/mojo",
+ "//media",
+ "//media:shared_memory_support",
+ "//media/gpu/ipc/client",
+ "//media/gpu/ipc/common",
+ "//media/midi",
+ "//mojo/common:common_base",
+ "//mojo/edk/system",
+ "//mojo/shell",
"//mojo/shell/public/cpp",
+ "//mojo/shell/public/interfaces",
+ "//mojo/shell/runner/common",
"//net",
+ "//sandbox",
"//skia",
+ "//storage/common",
+ "//third_party/WebKit/public:blink",
+ "//third_party/boringssl",
"//third_party/icu",
"//third_party/libjingle",
+ "//third_party/webrtc/base:rtc_base",
"//ui/accessibility",
"//ui/base",
"//ui/base/ime",
- "//ui/events/ipc:events_ipc",
+ "//ui/events/ipc",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/ipc",
+ "//ui/gfx/ipc/skia",
+ "//ui/gl",
"//ui/shell_dialogs",
"//url",
+ "//url/ipc:url_ipc",
]
- if (!is_ios) {
- deps += [
- "//cc",
- "//device/bluetooth",
- "//ipc",
- "//ipc/mojo",
-
- # TODO: the dependency on gl_in_process_context should be decoupled from
- # content and moved to android_webview. See crbug.com/365797.
- ":mojo_bindings",
- "//gpu/blink",
- "//gpu/command_buffer/client:gl_in_process_context",
- "//gpu/command_buffer/client:gles2_c_lib",
- "//gpu/command_buffer/client:gles2_cmd_helper",
- "//gpu/command_buffer/client:gles2_implementation",
- "//gpu/command_buffer/service",
- "//gpu/ipc",
- "//gpu/skia_bindings",
- "//media",
- "//media:shared_memory_support",
- "//media/midi",
- "//mojo/common:common_base",
- "//mojo/environment:chromium",
- "//mojo/shell/public/interfaces",
- "//sandbox",
- "//storage/common",
- "//third_party/WebKit/public:blink",
- "//third_party/boringssl",
- "//third_party/mojo/src/mojo/edk/system",
- "//ui/gl",
- ]
- }
-
defines = []
include_dirs = []
libs = []
@@ -227,17 +230,13 @@ source_set("common") {
if (is_mac) {
sources += [
- "gpu/client/gpu_memory_buffer_impl_io_surface.cc",
- "gpu/client/gpu_memory_buffer_impl_io_surface.h",
- "gpu/gpu_memory_buffer_factory_io_surface.cc",
- "gpu/gpu_memory_buffer_factory_io_surface.h",
"gpu/media/vt_mac.h",
"gpu/media/vt_video_decode_accelerator_mac.cc",
"gpu/media/vt_video_decode_accelerator_mac.h",
+ "gpu/media/vt_video_encode_accelerator_mac.cc",
+ "gpu/media/vt_video_encode_accelerator_mac.h",
] + get_target_outputs(":libvt_generate_stubs")
- sources -= [ "plugin_list_posix.cc" ]
-
deps += [
":libvt_generate_stubs",
"//content:resources",
@@ -248,6 +247,9 @@ source_set("common") {
]
lib_dirs = [ "$mac_sdk_path/usr/lib" ]
libs += [
+ "AVFoundation.framework",
+ "CoreMedia.framework",
+ "CoreVideo.framework",
"IOSurface.framework",
"OpenGL.framework",
"QuartzCore.framework",
@@ -256,13 +258,6 @@ source_set("common") {
}
if (is_android) {
- sources += [
- "gpu/client/gpu_memory_buffer_impl_surface_texture.cc",
- "gpu/client/gpu_memory_buffer_impl_surface_texture.h",
- "gpu/gpu_memory_buffer_factory_surface_texture.cc",
- "gpu/gpu_memory_buffer_factory_surface_texture.h",
- ]
-
deps += [
"//content/public/android:common_aidl",
"//content/public/android:jni",
@@ -278,26 +273,12 @@ source_set("common") {
deps += [ "//ppapi/proxy:ipc_sources" ]
}
- if (is_ios) {
- sources -= [ "user_agent.cc" ]
- assert(false, "Need to add lots of conditions here")
- }
-
if (use_ozone) {
- configs += [ "//ui/ozone:vgem_map" ]
-
- deps += [
- "//ui/ozone:ozone",
- "//ui/ozone:ozone_base",
- ]
+ deps += [ "//ui/ozone" ]
} else {
sources -= [
"cursors/webcursor_ozone.cc",
"font_list_ozone.cc",
- "gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc",
- "gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h",
- "gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc",
- "gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h",
]
}
@@ -320,17 +301,6 @@ source_set("common") {
sources -= [ "font_list_pango.cc" ]
}
- if (use_x11) {
- configs += [
- "//build/config/linux:xcomposite",
- "//third_party/khronos:khronos_headers",
- ]
-
- if (current_cpu != "arm" || !is_chromeos) {
- sources += [ "gpu/x_util.h" ]
- }
- }
-
if (enable_plugins) {
deps += [ "//ppapi/shared_impl" ]
} else {
@@ -344,7 +314,6 @@ source_set("common") {
"pepper_renderer_instance_data.h",
"plugin_list.cc",
"plugin_list.h",
- "plugin_list_posix.cc",
"sandbox_util.cc",
]
}
@@ -373,16 +342,14 @@ source_set("common") {
]
}
- if (enable_mojo_media == "gpu") {
- deps += [ "//media/mojo/services:application" ]
+ if (mojo_media_host == "gpu") {
+ deps += [ "//media/mojo/services:cdm_service" ]
}
}
if (is_chromeos) {
sources += [
"gpu/media/accelerated_video_decoder.h",
- "gpu/media/gpu_arc_video_service.cc",
- "gpu/media/gpu_arc_video_service.h",
"gpu/media/h264_decoder.cc",
"gpu/media/h264_decoder.h",
"gpu/media/h264_dpb.cc",
@@ -396,7 +363,6 @@ source_set("common") {
"gpu/media/vp9_picture.cc",
"gpu/media/vp9_picture.h",
]
- deps += [ "//components/arc" ]
if (use_v4lplugin) {
defines += [ "USE_LIBV4L2" ]
sources += get_target_outputs(":libv4l2_generate_stubs")
@@ -531,30 +497,50 @@ source_set("common") {
}
}
+# See comment at the top of //content/BUILD.gn for how this works.
+group("for_content_tests") {
+ visibility = [ "//content/test/*" ]
+ if (!is_component_build) {
+ public_deps = [
+ ":common",
+ ]
+ }
+}
+
mojom("mojo_bindings") {
+ # This interface is internal to content. However, this is not exported from
+ # the content component shared library. Code in content but outside of the
+ # content component (content/test or content/shell) should link to this
+ # directly.
+ visibility = [ "//content/*" ]
+
sources = [
"application_setup.mojom",
"background_sync_service.mojom",
- "geolocation_service.mojom",
"image_downloader/image_downloader.mojom",
- "permission_service.mojom",
+ "leveldb_wrapper.mojom",
"presentation/presentation_service.mojom",
"process_control.mojom",
"render_frame_setup.mojom",
"render_widget_window_tree_client_factory.mojom",
- "service_port_service.mojom",
"service_worker/embedded_worker_setup.mojom",
+ "storage_partition_service.mojom",
"vr_service.mojom",
"wake_lock_service.mojom",
]
import_dirs = [ "//mojo/services" ]
- deps = [
+ typemaps = [ "//url/mojo/origin.typemap" ]
+
+ public_deps = [
+ "//components/leveldb/public/interfaces",
"//components/mus/public/interfaces",
"//content/public/common:mojo_bindings",
"//mojo/shell/public/interfaces",
"//skia/public/interfaces",
+ "//third_party/WebKit/public:mojo_bindings",
"//ui/mojo/geometry:interfaces",
+ "//url/mojo:url_mojom_origin",
]
}
diff --git a/chromium/content/common/DEPS b/chromium/content/common/DEPS
index 3ba16c40dc2..caf3f5d1ead 100644
--- a/chromium/content/common/DEPS
+++ b/chromium/content/common/DEPS
@@ -6,7 +6,7 @@ include_rules = [
# No inclusion of WebKit from the browser, other than strictly enum/POD,
# header-only types, and some selected common code.
"-third_party/WebKit",
- "+third_party/WebKit/public/platform/WebBatteryStatus.h",
+ "+third_party/WebKit/public/platform/WebAddressSpace.h",
"+third_party/WebKit/public/platform/WebCircularGeofencingRegion.h",
"+third_party/WebKit/public/platform/WebCString.h",
"+third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionData.h",
@@ -65,10 +65,3 @@ include_rules = [
"+third_party/WebKit/public/web/mac/WebScrollbarTheme.h",
"+third_party/WebKit/public/web/win/WebFontRendering.h"
]
-
-specific_include_rules = {
-# Java bridge code passes NPAPI types to the browser process. Crazy!
- "java_bridge_messages\.h": [
- "+content/child"
- ]
-}
diff --git a/chromium/content/common/OWNERS b/chromium/content/common/OWNERS
index df1d46c544f..8ded209736c 100644
--- a/chromium/content/common/OWNERS
+++ b/chromium/content/common/OWNERS
@@ -72,8 +72,17 @@ per-file *font_config_ipc_linux*=wfh@chromium.org
# Changes to Mojo interfaces require a security review to avoid
# introducing new sandbox escapes.
per-file *.mojom=set noparent
+per-file *.mojom=dcheng@chromium.org
+per-file *.mojom=inferno@chromium.org
+per-file *.mojom=jln@chromium.org
+per-file *.mojom=jschuh@chromium.org
+per-file *.mojom=kenrb@chromium.org
+per-file *.mojom=mkwst@chromium.org
+per-file *.mojom=nasko@chromium.org
per-file *.mojom=palmer@chromium.org
per-file *.mojom=tsepez@chromium.org
+per-file *.mojom=wfh@chromium.org
+
# Accessibility
per-file accessibility_node_data.*=dmazzoni@chromium.org
@@ -91,3 +100,7 @@ per-file cc_messages_perftest.cc=danakj@chromium.org
# DirectWrite
per-file dwrite_font_platform_win*=scottmg@chromium.org
per-file font_warmup_win.cc=scottmg@chromium.org
+
+# Web Notifications
+per-file notification_constants.h=peter@chromium.org
+per-file notification_constants.h=mvanouwerkerk@chromium.org
diff --git a/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.cc b/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.cc
new file mode 100644
index 00000000000..c9eb1d204ce
--- /dev/null
+++ b/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.cc
@@ -0,0 +1,14 @@
+// Copyright 2016 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 "content/common/accelerated_surface_buffers_swapped_params_mac.h"
+
+namespace content {
+AcceleratedSurfaceBuffersSwappedParams::AcceleratedSurfaceBuffersSwappedParams()
+ : surface_id(0), ca_context_id(0), scale_factor(1.f) {}
+
+AcceleratedSurfaceBuffersSwappedParams::
+ ~AcceleratedSurfaceBuffersSwappedParams() {}
+
+} // namespace content
diff --git a/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.h b/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.h
new file mode 100644
index 00000000000..71fb4ffd777
--- /dev/null
+++ b/chromium/content/common/accelerated_surface_buffers_swapped_params_mac.h
@@ -0,0 +1,28 @@
+// Copyright 2016 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 CONTENT_COMMON_ACCELERATED_SURFACE_BUFFERS_SWAPPED_PARAMS_MAC_H_
+#define CONTENT_COMMON_ACCELERATED_SURFACE_BUFFERS_SWAPPED_PARAMS_MAC_H_
+
+#include "ui/base/cocoa/remote_layer_api.h"
+#include "ui/events/latency_info.h"
+#include "ui/gfx/mac/io_surface.h"
+
+namespace content {
+
+struct AcceleratedSurfaceBuffersSwappedParams {
+ AcceleratedSurfaceBuffersSwappedParams();
+ ~AcceleratedSurfaceBuffersSwappedParams();
+
+ int32_t surface_id;
+ CAContextID ca_context_id;
+ gfx::ScopedRefCountedIOSurfaceMachPort io_surface;
+ gfx::Size size;
+ float scale_factor;
+ std::vector<ui::LatencyInfo> latency_info;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_ACCELERATED_SURFACE_BUFFERS_SWAPPED_PARAMS_MAC_H_
diff --git a/chromium/content/common/accessibility_messages.h b/chromium/content/common/accessibility_messages.h
index f30b5e41660..2a300eab93a 100644
--- a/chromium/content/common/accessibility_messages.h
+++ b/chromium/content/common/accessibility_messages.h
@@ -8,7 +8,6 @@
#include "content/common/ax_content_node_data.h"
#include "content/common/content_export.h"
#include "content/common/view_message_enums.h"
-#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_param_traits.h"
@@ -16,6 +15,7 @@
#include "third_party/WebKit/public/web/WebAXEnums.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_tree_update.h"
+#include "ui/gfx/transform.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -30,6 +30,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::AXContentNodeData)
IPC_STRUCT_TRAITS_MEMBER(role)
IPC_STRUCT_TRAITS_MEMBER(state)
IPC_STRUCT_TRAITS_MEMBER(location)
+ IPC_STRUCT_TRAITS_MEMBER(transform)
IPC_STRUCT_TRAITS_MEMBER(string_attributes)
IPC_STRUCT_TRAITS_MEMBER(int_attributes)
IPC_STRUCT_TRAITS_MEMBER(float_attributes)
@@ -43,12 +44,14 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::AXContentTreeData)
IPC_STRUCT_TRAITS_MEMBER(tree_id)
IPC_STRUCT_TRAITS_MEMBER(parent_tree_id)
+ IPC_STRUCT_TRAITS_MEMBER(focused_tree_id)
IPC_STRUCT_TRAITS_MEMBER(url)
IPC_STRUCT_TRAITS_MEMBER(title)
IPC_STRUCT_TRAITS_MEMBER(mimetype)
IPC_STRUCT_TRAITS_MEMBER(doctype)
IPC_STRUCT_TRAITS_MEMBER(loaded)
IPC_STRUCT_TRAITS_MEMBER(loading_progress)
+ IPC_STRUCT_TRAITS_MEMBER(focus_id)
IPC_STRUCT_TRAITS_MEMBER(sel_anchor_object_id)
IPC_STRUCT_TRAITS_MEMBER(sel_anchor_offset)
IPC_STRUCT_TRAITS_MEMBER(sel_focus_object_id)
@@ -156,8 +159,13 @@ IPC_MESSAGE_ROUTED2(AccessibilityMsg_SetValue,
int /* object id */,
base::string16 /* Value */)
-// Determine the accessibility object under a given point and reply with
-// a AccessibilityHostMsg_HitTestResult with the same id.
+// Determine the accessibility object under a given point.
+//
+// If the target is an object with a child frame (like if the hit test
+// result is an iframe element), it responds with
+// AccessibilityHostMsg_ChildFrameHitTestResult so that the
+// hit test can be performed recursively on the child frame. Otherwise
+// it fires an accessibility event of type ui::AX_EVENT_HOVER on the target.
IPC_MESSAGE_ROUTED1(AccessibilityMsg_HitTest,
gfx::Point /* location to test */)
@@ -210,11 +218,16 @@ IPC_MESSAGE_ROUTED1(
AccessibilityHostMsg_LocationChanges,
std::vector<AccessibilityHostMsg_LocationChangeParams>)
-// Sent to update the browser of the location of accessibility objects.
+// Sent to update the browser of Find In Page results.
IPC_MESSAGE_ROUTED1(
AccessibilityHostMsg_FindInPageResult,
AccessibilityHostMsg_FindInPageResultParams)
+// Sent in response to AccessibilityMsg_HitTest.
+IPC_MESSAGE_ROUTED2(AccessibilityHostMsg_ChildFrameHitTestResult,
+ gfx::Point /* location tested */,
+ int /* node id of result */)
+
// Sent in response to AccessibilityMsg_SnapshotTree. The callback id that was
// passed to the request will be returned in |callback_id|, along with
// a standalone snapshot of the accessibility tree.
diff --git a/chromium/content/common/android/address_parser_internal.cc b/chromium/content/common/android/address_parser_internal.cc
index 4f114a3f106..9892bd853fb 100644
--- a/chromium/content/common/android/address_parser_internal.cc
+++ b/chromium/content/common/android/address_parser_internal.cc
@@ -77,6 +77,8 @@ Word::Word(const base::string16::const_iterator& begin,
DCHECK(begin <= end);
}
+Word::Word(const Word& other) = default;
+
HouseNumberParser::HouseNumberParser() {
}
diff --git a/chromium/content/common/android/address_parser_internal.h b/chromium/content/common/android/address_parser_internal.h
index 5defd08de2a..60c1483fc03 100644
--- a/chromium/content/common/android/address_parser_internal.h
+++ b/chromium/content/common/android/address_parser_internal.h
@@ -28,6 +28,7 @@ struct CONTENT_EXPORT Word {
Word();
Word(const base::string16::const_iterator& begin,
const base::string16::const_iterator& end);
+ Word(const Word& other);
};
// Exposed for tests.
diff --git a/chromium/content/common/android/media_metadata_android.cc b/chromium/content/common/android/media_metadata_android.cc
new file mode 100644
index 00000000000..0bd15631758
--- /dev/null
+++ b/chromium/content/common/android/media_metadata_android.cc
@@ -0,0 +1,33 @@
+// Copyright 2016 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 "content/common/android/media_metadata_android.h"
+
+#include "base/android/jni_string.h"
+#include "content/public/common/media_metadata.h"
+#include "jni/MediaMetadata_jni.h"
+
+namespace content {
+
+// static
+base::android::ScopedJavaLocalRef<jobject>
+MediaMetadataAndroid::CreateJavaObject(
+ JNIEnv* env, const MediaMetadata& metadata) {
+ ScopedJavaLocalRef<jstring> j_title(
+ base::android::ConvertUTF16ToJavaString(env, metadata.title));
+ ScopedJavaLocalRef<jstring> j_artist(
+ base::android::ConvertUTF16ToJavaString(env, metadata.artist));
+ ScopedJavaLocalRef<jstring> j_album(
+ base::android::ConvertUTF16ToJavaString(env, metadata.album));
+
+ return Java_MediaMetadata_create(
+ env, j_title.obj(), j_artist.obj(), j_album.obj());
+}
+
+// static
+bool MediaMetadataAndroid::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace content
diff --git a/chromium/content/common/android/media_metadata_android.h b/chromium/content/common/android/media_metadata_android.h
new file mode 100644
index 00000000000..e580e53af0f
--- /dev/null
+++ b/chromium/content/common/android/media_metadata_android.h
@@ -0,0 +1,29 @@
+// Copyright 2016 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 CONTENT_COMMON_ANDROID_MEDIA_METADATA_ANDROID_H_
+#define CONTENT_COMMON_ANDROID_MEDIA_METADATA_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+
+namespace content {
+
+struct MediaMetadata;
+
+class MediaMetadataAndroid {
+ public:
+ static base::android::ScopedJavaLocalRef<jobject> CreateJavaObject(
+ JNIEnv* env, const MediaMetadata& metadata);
+
+ static bool Register(JNIEnv* env);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(MediaMetadataAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_ANDROID_MEDIA_METADATA_ANDROID_H_
diff --git a/chromium/content/common/android/surface_texture_manager.cc b/chromium/content/common/android/surface_texture_manager.cc
deleted file mode 100644
index c2cb6eeb983..00000000000
--- a/chromium/content/common/android/surface_texture_manager.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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 "content/common/android/surface_texture_manager.h"
-
-#include "base/logging.h"
-
-namespace content {
-namespace {
-
-SurfaceTextureManager* g_instance = NULL;
-
-} // namespace
-
-// static
-SurfaceTextureManager* SurfaceTextureManager::GetInstance() {
- DCHECK(g_instance);
- return g_instance;
-}
-
-// static
-void SurfaceTextureManager::SetInstance(SurfaceTextureManager* instance) {
- DCHECK(!g_instance || !instance);
- g_instance = instance;
-}
-
-} // namespace content
diff --git a/chromium/content/common/android/surface_texture_manager.h b/chromium/content/common/android/surface_texture_manager.h
deleted file mode 100644
index 30a17dc9e15..00000000000
--- a/chromium/content/common/android/surface_texture_manager.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_MANAGER_H_
-#define CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_MANAGER_H_
-
-#include "content/common/content_export.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace gfx {
-class SurfaceTexture;
-}
-
-namespace content {
-
-class CONTENT_EXPORT SurfaceTextureManager {
- public:
- static SurfaceTextureManager* GetInstance();
- static void SetInstance(SurfaceTextureManager* instance);
-
- // Register a surface texture for use in another process.
- virtual void RegisterSurfaceTexture(int surface_texture_id,
- int client_id,
- gfx::SurfaceTexture* surface_texture) = 0;
-
- // Unregister a surface texture previously registered for use in another
- // process.
- virtual void UnregisterSurfaceTexture(int surface_texture_id,
- int client_id) = 0;
-
- // Acquire native widget for a registered surface texture.
- virtual gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture(
- int surface_texture_id) = 0;
-
- protected:
- virtual ~SurfaceTextureManager() {}
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_MANAGER_H_
diff --git a/chromium/content/common/android/surface_texture_peer.cc b/chromium/content/common/android/surface_texture_peer.cc
deleted file mode 100644
index a6fade45e69..00000000000
--- a/chromium/content/common/android/surface_texture_peer.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 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 "content/common/android/surface_texture_peer.h"
-
-#include "base/logging.h"
-
-namespace content {
-
-namespace {
-SurfaceTexturePeer* g_instance_ = NULL;
-} // namespace
-
-SurfaceTexturePeer::SurfaceTexturePeer() {
-}
-
-SurfaceTexturePeer::~SurfaceTexturePeer() {
-}
-
-// static
-SurfaceTexturePeer* SurfaceTexturePeer::GetInstance() {
- DCHECK(g_instance_);
- return g_instance_;
-}
-
-// static
-void SurfaceTexturePeer::InitInstance(SurfaceTexturePeer* instance) {
- DCHECK(!g_instance_);
- g_instance_ = instance;
-}
-
-} // namespace content
diff --git a/chromium/content/common/android/surface_texture_peer.h b/chromium/content/common/android/surface_texture_peer.h
deleted file mode 100644
index 0afe3efcf53..00000000000
--- a/chromium/content/common/android/surface_texture_peer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_PEER_H_
-#define CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_PEER_H_
-
-#include "base/macros.h"
-#include "base/process/process.h"
-#include "ui/gl/android/surface_texture.h"
-
-namespace content {
-
-class SurfaceTexturePeer {
- public:
- static SurfaceTexturePeer* GetInstance();
-
- static void InitInstance(SurfaceTexturePeer* instance);
-
- // Establish the producer end for the given surface texture in another
- // process.
- virtual void EstablishSurfaceTexturePeer(
- base::ProcessHandle pid,
- scoped_refptr<gfx::SurfaceTexture> surface_texture,
- int primary_id,
- int secondary_id) = 0;
-
- protected:
- SurfaceTexturePeer();
- virtual ~SurfaceTexturePeer();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SurfaceTexturePeer);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_PEER_H_
diff --git a/chromium/content/common/android/sync_compositor_messages.cc b/chromium/content/common/android/sync_compositor_messages.cc
index f44415f375f..1423091bd74 100644
--- a/chromium/content/common/android/sync_compositor_messages.cc
+++ b/chromium/content/common/android/sync_compositor_messages.cc
@@ -8,6 +8,7 @@ namespace content {
SyncCompositorCommonBrowserParams::SyncCompositorCommonBrowserParams()
: bytes_limit(0u),
+ output_surface_id_for_returned_resources(0u),
update_root_scroll_offset(false),
begin_frame_source_paused(false) {}
@@ -44,9 +45,9 @@ SyncCompositorCommonRendererParams::SyncCompositorCommonRendererParams()
min_page_scale_factor(0.f),
max_page_scale_factor(0.f),
need_animate_scroll(false),
- need_invalidate(false),
+ need_invalidate_count(0u),
need_begin_frame(false),
- did_activate_pending_tree(false) {}
+ did_activate_pending_tree_count(0u) {}
SyncCompositorCommonRendererParams::~SyncCompositorCommonRendererParams() {}
diff --git a/chromium/content/common/android/sync_compositor_messages.h b/chromium/content/common/android/sync_compositor_messages.h
index a91440764b8..0ec4bf4cec5 100644
--- a/chromium/content/common/android/sync_compositor_messages.h
+++ b/chromium/content/common/android/sync_compositor_messages.h
@@ -14,6 +14,7 @@
#include "content/common/input/input_event_ack_state.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/scroll_offset.h"
#ifndef CONTENT_COMMON_ANDROID_SYNC_COMPOSITOR_MESSAGES_H_
@@ -25,7 +26,8 @@ struct SyncCompositorCommonBrowserParams {
SyncCompositorCommonBrowserParams();
~SyncCompositorCommonBrowserParams();
- size_t bytes_limit;
+ uint32_t bytes_limit;
+ uint32_t output_surface_id_for_returned_resources;
cc::CompositorFrameAck ack;
gfx::ScrollOffset root_scroll_offset;
bool update_root_scroll_offset;
@@ -54,7 +56,7 @@ struct SyncCompositorDemandDrawHwParams {
struct SyncCompositorSetSharedMemoryParams {
SyncCompositorSetSharedMemoryParams();
- size_t buffer_size;
+ uint32_t buffer_size;
base::SharedMemoryHandle shm_handle;
};
@@ -79,9 +81,9 @@ struct SyncCompositorCommonRendererParams {
float min_page_scale_factor;
float max_page_scale_factor;
bool need_animate_scroll;
- bool need_invalidate;
+ uint32_t need_invalidate_count;
bool need_begin_frame;
- bool did_activate_pending_tree;
+ uint32_t did_activate_pending_tree_count;
};
} // namespace content
@@ -96,6 +98,7 @@ struct SyncCompositorCommonRendererParams {
IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonBrowserParams)
IPC_STRUCT_TRAITS_MEMBER(bytes_limit)
+ IPC_STRUCT_TRAITS_MEMBER(output_surface_id_for_returned_resources)
IPC_STRUCT_TRAITS_MEMBER(ack)
IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset)
IPC_STRUCT_TRAITS_MEMBER(update_root_scroll_offset)
@@ -131,12 +134,14 @@ IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonRendererParams)
IPC_STRUCT_TRAITS_MEMBER(min_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(need_animate_scroll)
- IPC_STRUCT_TRAITS_MEMBER(need_invalidate)
+ IPC_STRUCT_TRAITS_MEMBER(need_invalidate_count)
IPC_STRUCT_TRAITS_MEMBER(need_begin_frame)
- IPC_STRUCT_TRAITS_MEMBER(did_activate_pending_tree)
+ IPC_STRUCT_TRAITS_MEMBER(did_activate_pending_tree_count)
IPC_STRUCT_TRAITS_END()
// Messages sent from the browser to the renderer.
+// Synchronous IPCs are allowed here to the renderer compositor thread. See
+// design doc https://goo.gl/Tn81FW and crbug.com/526842 for details.
IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_HandleInputEvent,
content::SyncCompositorCommonBrowserParams,
@@ -149,15 +154,15 @@ IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_BeginFrame,
cc::BeginFrameArgs,
content::SyncCompositorCommonRendererParams)
-IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_ComputeScroll,
- content::SyncCompositorCommonBrowserParams,
- base::TimeTicks,
- content::SyncCompositorCommonRendererParams)
+IPC_MESSAGE_ROUTED2(SyncCompositorMsg_ComputeScroll,
+ content::SyncCompositorCommonBrowserParams,
+ base::TimeTicks);
-IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_DemandDrawHw,
+IPC_SYNC_MESSAGE_ROUTED2_3(SyncCompositorMsg_DemandDrawHw,
content::SyncCompositorCommonBrowserParams,
content::SyncCompositorDemandDrawHwParams,
content::SyncCompositorCommonRendererParams,
+ uint32_t /* output_surface_id */,
cc::CompositorFrame)
IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_SetSharedMemory,
@@ -178,6 +183,12 @@ IPC_SYNC_MESSAGE_ROUTED2_3(SyncCompositorMsg_DemandDrawSw,
IPC_MESSAGE_ROUTED1(SyncCompositorMsg_UpdateState,
content::SyncCompositorCommonBrowserParams)
+IPC_SYNC_MESSAGE_ROUTED3_1(SyncCompositorMsg_ZoomBy,
+ content::SyncCompositorCommonBrowserParams,
+ float /* delta */,
+ gfx::Point /* anchor */,
+ content::SyncCompositorCommonRendererParams)
+
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
diff --git a/chromium/content/common/appcache_interfaces.cc b/chromium/content/common/appcache_interfaces.cc
index af0d8c16883..8342a364f0f 100644
--- a/chromium/content/common/appcache_interfaces.cc
+++ b/chromium/content/common/appcache_interfaces.cc
@@ -31,6 +31,8 @@ AppCacheInfo::AppCacheInfo()
is_complete(false) {
}
+AppCacheInfo::AppCacheInfo(const AppCacheInfo& other) = default;
+
AppCacheInfo::~AppCacheInfo() {
}
@@ -46,6 +48,9 @@ AppCacheResourceInfo::AppCacheResourceInfo()
response_id(kAppCacheNoResponseId) {
}
+AppCacheResourceInfo::AppCacheResourceInfo(const AppCacheResourceInfo& other) =
+ default;
+
AppCacheResourceInfo::~AppCacheResourceInfo() {
}
diff --git a/chromium/content/common/appcache_interfaces.h b/chromium/content/common/appcache_interfaces.h
index 8ba2da072b9..12cc7c11d5d 100644
--- a/chromium/content/common/appcache_interfaces.h
+++ b/chromium/content/common/appcache_interfaces.h
@@ -62,6 +62,7 @@ enum AppCacheErrorReason {
// Type to hold information about a single appcache resource.
struct CONTENT_EXPORT AppCacheResourceInfo {
AppCacheResourceInfo();
+ AppCacheResourceInfo(const AppCacheResourceInfo& other);
~AppCacheResourceInfo();
GURL url;
diff --git a/chromium/content/common/appcache_messages.h b/chromium/content/common/appcache_messages.h
index 7e74848e4dd..95964f71c9d 100644
--- a/chromium/content/common/appcache_messages.h
+++ b/chromium/content/common/appcache_messages.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "content/common/appcache_interfaces.h"
+#include "url/ipc/url_param_traits.h"
#define IPC_MESSAGE_START AppCacheMsgStart
diff --git a/chromium/content/common/application_setup.mojom b/chromium/content/common/application_setup.mojom
index df45c5ac22f..8fb0e174c88 100644
--- a/chromium/content/common/application_setup.mojom
+++ b/chromium/content/common/application_setup.mojom
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
-import "mojo/shell/public/interfaces/service_provider.mojom";
+import "mojo/shell/public/interfaces/interface_provider.mojom";
interface ApplicationSetup {
- ExchangeServiceProviders(mojo.ServiceProvider& services,
- mojo.ServiceProvider exposed_services);
+ ExchangeInterfaceProviders(
+ mojo.shell.mojom.InterfaceProvider& remote_interfaces,
+ mojo.shell.mojom.InterfaceProvider local_interfaces);
};
diff --git a/chromium/content/common/ax_content_node_data.cc b/chromium/content/common/ax_content_node_data.cc
index fda36683ca4..d528727aa87 100644
--- a/chromium/content/common/ax_content_node_data.cc
+++ b/chromium/content/common/ax_content_node_data.cc
@@ -33,6 +33,8 @@ typename std::vector<std::pair<FirstType, SecondType>>::const_iterator
AXContentNodeData::AXContentNodeData() {
}
+AXContentNodeData::AXContentNodeData(const AXContentNodeData& other) = default;
+
AXContentNodeData::~AXContentNodeData() {
}
diff --git a/chromium/content/common/ax_content_node_data.h b/chromium/content/common/ax_content_node_data.h
index 00849cdae6a..93ab7191942 100644
--- a/chromium/content/common/ax_content_node_data.h
+++ b/chromium/content/common/ax_content_node_data.h
@@ -28,6 +28,7 @@ enum AXContentIntAttribute {
// content-layer-specific AX attributes.
struct CONTENT_EXPORT AXContentNodeData : public ui::AXNodeData {
AXContentNodeData();
+ AXContentNodeData(const AXContentNodeData& other);
~AXContentNodeData() override;
bool HasContentIntAttribute(AXContentIntAttribute attribute) const;
diff --git a/chromium/content/common/background_sync_service.mojom b/chromium/content/common/background_sync_service.mojom
index d1b0cd1089c..cceb58c31b3 100644
--- a/chromium/content/common/background_sync_service.mojom
+++ b/chromium/content/common/background_sync_service.mojom
@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
import "content/public/common/background_sync.mojom";
-import "content/public/common/permission_status.mojom";
import "content/public/common/service_worker_event_status.mojom";
enum BackgroundSyncError {
@@ -14,17 +13,14 @@ enum BackgroundSyncError {
NOT_FOUND,
NO_SERVICE_WORKER,
NOT_ALLOWED,
- MAX=NOT_ALLOWED
+ PERMISSION_DENIED,
+ MAX=PERMISSION_DENIED
};
enum BackgroundSyncState {
PENDING,
FIRING,
- UNREGISTERED_WHILE_FIRING,
REREGISTERED_WHILE_FIRING,
- FAILED,
- SUCCESS,
- UNREGISTERED
};
enum BackgroundSyncEventLastChance {
@@ -33,28 +29,14 @@ enum BackgroundSyncEventLastChance {
};
interface BackgroundSyncService {
- Register(SyncRegistration options, int64 service_worker_registration_id,
- bool requested_from_service_worker)
+ Register(SyncRegistration options, int64 service_worker_registration_id)
=> (BackgroundSyncError err, SyncRegistration options);
- GetRegistration(BackgroundSyncPeriodicity periodicity, string tag,
- int64 service_worker_registration_id)
- => (BackgroundSyncError err, SyncRegistration? registration);
- GetRegistrations(BackgroundSyncPeriodicity periodicity,
- int64 service_worker_registration_id)
+ GetRegistrations(int64 service_worker_registration_id)
=> (BackgroundSyncError err, array<SyncRegistration> registrations);
- Unregister(int64 handle_id, int64 service_worker_registration_id)
- => (BackgroundSyncError err);
- GetPermissionStatus(BackgroundSyncPeriodicity periodicity,
- int64 service_worker_registration_id)
- => (BackgroundSyncError err, PermissionStatus status);
- DuplicateRegistrationHandle(int64 handle_id)
- => (BackgroundSyncError err, SyncRegistration? registration);
- ReleaseRegistration(int64 handle_id);
- NotifyWhenFinished(int64 handle_id) => (BackgroundSyncError err, BackgroundSyncState final_status);
};
interface BackgroundSyncServiceClient {
- Sync(int64 handle_id, BackgroundSyncEventLastChance last_chance)
+ Sync(string tag, BackgroundSyncEventLastChance last_chance)
=> (ServiceWorkerEventStatus status);
};
diff --git a/chromium/content/common/bluetooth/bluetooth_messages.h b/chromium/content/common/bluetooth/bluetooth_messages.h
index df7695d67f4..68b51e34f61 100644
--- a/chromium/content/common/bluetooth/bluetooth_messages.h
+++ b/chromium/content/common/bluetooth/bluetooth_messages.h
@@ -129,13 +129,12 @@ IPC_MESSAGE_CONTROL3(BluetoothMsg_RequestDeviceError,
blink::WebBluetoothError /* result */)
// Informs the renderer that the connection request |request_id| succeeded.
-IPC_MESSAGE_CONTROL3(BluetoothMsg_ConnectGATTSuccess,
+IPC_MESSAGE_CONTROL2(BluetoothMsg_GATTServerConnectSuccess,
int /* thread_id */,
- int /* request_id */,
- std::string /* device_id */)
+ int /* request_id */)
// Informs the renderer that the connection request |request_id| failed.
-IPC_MESSAGE_CONTROL3(BluetoothMsg_ConnectGATTError,
+IPC_MESSAGE_CONTROL3(BluetoothMsg_GATTServerConnectError,
int /* thread_id */,
int /* request_id */,
blink::WebBluetoothError /* result */)
@@ -165,6 +164,23 @@ IPC_MESSAGE_CONTROL3(BluetoothMsg_GetCharacteristicError,
int /* request_id */,
blink::WebBluetoothError /* result */)
+// Informs the renderer that the multiple-characteristic request |request_id|
+// succeeded.
+IPC_MESSAGE_CONTROL5(
+ BluetoothMsg_GetCharacteristicsSuccess,
+ int /* thread_id */,
+ int /* request_id */,
+ std::vector<std::string> /* characteristics_instance_ids */,
+ std::vector<std::string> /* characteristics_uuids */,
+ std::vector<uint32_t> /* characteristics_properties */)
+
+// Informs the renderer that the multiple-characteristic request |request_id|
+// failed.
+IPC_MESSAGE_CONTROL3(BluetoothMsg_GetCharacteristicsError,
+ int /* thread_id */,
+ int /* request_id */,
+ blink::WebBluetoothError /* result */)
+
// Informs the renderer that the value has been read.
IPC_MESSAGE_CONTROL3(BluetoothMsg_ReadCharacteristicValueSuccess,
int /* thread_id */,
@@ -177,19 +193,6 @@ IPC_MESSAGE_CONTROL3(BluetoothMsg_ReadCharacteristicValueError,
int /* request_id */,
blink::WebBluetoothError /* result */)
-// Informs the renderer that the value has been successfully written to
-// the characteristic.
-IPC_MESSAGE_CONTROL2(BluetoothMsg_WriteCharacteristicValueSuccess,
- int /* thread_id */,
- int /* request_id */)
-
-// Informs the renderer that an error occurred while writing a value to a
-// characteristic.
-IPC_MESSAGE_CONTROL3(BluetoothMsg_WriteCharacteristicValueError,
- int /* thread_id */,
- int /* request_id */,
- blink::WebBluetoothError /* result */)
-
// Informs the renderer that the user has successfully subscribed to
// notifications from the device.
IPC_MESSAGE_CONTROL2(BluetoothMsg_StartNotificationsSuccess,
@@ -226,12 +229,18 @@ IPC_MESSAGE_CONTROL5(BluetoothHostMsg_RequestDevice,
std::vector<device::BluetoothUUID> /* optional_services */)
// Connects to a bluetooth device.
-IPC_MESSAGE_CONTROL4(BluetoothHostMsg_ConnectGATT,
+IPC_MESSAGE_CONTROL4(BluetoothHostMsg_GATTServerConnect,
int /* thread_id */,
int /* request_id */,
int /* frame_routing_id */,
std::string /* device_id */)
+// Disconnect from a device.
+IPC_MESSAGE_CONTROL3(BluetoothHostMsg_GATTServerDisconnect,
+ int /* thread_id */,
+ int /* frame_routing_id */,
+ std::string /* device_id */)
+
// Gets primary service from bluetooth device.
IPC_MESSAGE_CONTROL5(BluetoothHostMsg_GetPrimaryService,
int /* thread_id */,
@@ -248,20 +257,20 @@ IPC_MESSAGE_CONTROL5(BluetoothHostMsg_GetCharacteristic,
std::string /* service_instance_id */,
std::string /* characteristic_uuid */)
-// Reads the characteristics value from a bluetooth device.
-IPC_MESSAGE_CONTROL4(BluetoothHostMsg_ReadValue,
+// Gets GATT Characteristics within a GATT Service.
+IPC_MESSAGE_CONTROL5(BluetoothHostMsg_GetCharacteristics,
int /* thread_id */,
int /* request_id */,
int /* frame_routing_id */,
- std::string /* characteristic_instance_id */)
+ std::string /* service_instance_id */,
+ std::string /* characteristics_uuid */)
-// Writes a value to a bluetooth device's characteristic.
-IPC_MESSAGE_CONTROL5(BluetoothHostMsg_WriteValue,
+// Reads the characteristics value from a bluetooth device.
+IPC_MESSAGE_CONTROL4(BluetoothHostMsg_ReadValue,
int /* thread_id */,
int /* request_id */,
int /* frame_routing_id */,
- std::string /* characteristic_instance_id */,
- std::vector<uint8_t> /* value */)
+ std::string /* characteristic_instance_id */)
// Subscribes to notifications from a device's characteristic.
IPC_MESSAGE_CONTROL4(BluetoothHostMsg_StartNotifications,
diff --git a/chromium/content/common/bluetooth/bluetooth_scan_filter.cc b/chromium/content/common/bluetooth/bluetooth_scan_filter.cc
index 3ab22aedfa3..2c5a7cb87a9 100644
--- a/chromium/content/common/bluetooth/bluetooth_scan_filter.cc
+++ b/chromium/content/common/bluetooth/bluetooth_scan_filter.cc
@@ -9,6 +9,9 @@ namespace content {
BluetoothScanFilter::BluetoothScanFilter() : services() {
}
+BluetoothScanFilter::BluetoothScanFilter(const BluetoothScanFilter& other) =
+ default;
+
BluetoothScanFilter::~BluetoothScanFilter() {
}
diff --git a/chromium/content/common/bluetooth/bluetooth_scan_filter.h b/chromium/content/common/bluetooth/bluetooth_scan_filter.h
index 257274729d3..6c0bb3374e1 100644
--- a/chromium/content/common/bluetooth/bluetooth_scan_filter.h
+++ b/chromium/content/common/bluetooth/bluetooth_scan_filter.h
@@ -17,6 +17,7 @@ namespace content {
// blink::WebBluetoothScanFilter.
struct CONTENT_EXPORT BluetoothScanFilter {
BluetoothScanFilter();
+ BluetoothScanFilter(const BluetoothScanFilter& other);
~BluetoothScanFilter();
std::vector<device::BluetoothUUID> services;
diff --git a/chromium/content/common/browser_plugin/browser_plugin_messages.h b/chromium/content/common/browser_plugin/browser_plugin_messages.h
index 1a264ce04a8..eef580508a6 100644
--- a/chromium/content/common/browser_plugin/browser_plugin_messages.h
+++ b/chromium/content/common/browser_plugin/browser_plugin_messages.h
@@ -12,8 +12,6 @@
#include "content/common/content_param_traits.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/edit_command.h"
-#include "content/common/frame_param_macros.h"
-#include "content/public/common/common_param_traits.h"
#include "content/public/common/drop_data.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
@@ -27,7 +25,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "url/gurl.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -112,18 +110,10 @@ IPC_MESSAGE_CONTROL3(BrowserPluginHostMsg_SetFocus,
blink::WebFocusType /* focus_type */)
// Sends an input event to the guest.
-IPC_MESSAGE_CONTROL3(BrowserPluginHostMsg_HandleInputEvent,
+IPC_MESSAGE_CONTROL2(BrowserPluginHostMsg_HandleInputEvent,
int /* browser_plugin_instance_id */,
- gfx::Rect /* guest_window_rect */,
IPC::WebInputEventPointer /* event */)
-// Notify the guest renderer that some resources given to the embededer
-// are not used any more.
-IPC_MESSAGE_CONTROL2(
- BrowserPluginHostMsg_ReclaimCompositorResources,
- int /* browser_plugin_instance_id */,
- FrameHostMsg_ReclaimCompositorResources_Params /* params */)
-
// Tells the guest it has been shown or hidden.
IPC_MESSAGE_CONTROL2(BrowserPluginHostMsg_SetVisibility,
int /* browser_plugin_instance_id */,
@@ -185,10 +175,6 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetCursor,
int /* browser_plugin_instance_id */,
content::WebCursor /* cursor */)
-IPC_MESSAGE_CONTROL2(BrowserPluginMsg_CompositorFrameSwapped,
- int /* browser_plugin_instance_id */,
- FrameMsg_CompositorFrameSwapped_Params /* params */)
-
IPC_MESSAGE_CONTROL5(BrowserPluginMsg_SetChildFrameSurface,
int /* browser_plugin_instance_id */,
cc::SurfaceId /* surface_id */,
@@ -205,8 +191,3 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetMouseLock,
IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetTooltipText,
int /* browser_plugin_instance_id */,
base::string16 /* tooltip_text */)
-
-// Acknowledge that we presented an ubercomp frame.
-IPC_MESSAGE_CONTROL2(BrowserPluginHostMsg_CompositorFrameSwappedACK,
- int /* browser_plugin_instance_id */,
- FrameHostMsg_CompositorFrameSwappedACK_Params /* params */)
diff --git a/chromium/content/common/buffer_presented_params_mac.cc b/chromium/content/common/buffer_presented_params_mac.cc
new file mode 100644
index 00000000000..795dc08fa4b
--- /dev/null
+++ b/chromium/content/common/buffer_presented_params_mac.cc
@@ -0,0 +1,13 @@
+// Copyright 2016 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 "content/common/buffer_presented_params_mac.h"
+
+namespace content {
+
+BufferPresentedParams::BufferPresentedParams() : surface_id(0) {}
+
+BufferPresentedParams::~BufferPresentedParams() {}
+
+} // namespace content
diff --git a/chromium/content/common/buffer_presented_params_mac.h b/chromium/content/common/buffer_presented_params_mac.h
new file mode 100644
index 00000000000..29e0dabf1b4
--- /dev/null
+++ b/chromium/content/common/buffer_presented_params_mac.h
@@ -0,0 +1,23 @@
+// Copyright 2016 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 CONTENT_COMMON_BUFFER_PRESENTED_PARAMS_MAC_H_
+#define CONTENT_COMMON_BUFFER_PRESENTED_PARAMS_MAC_H_
+
+#include "base/time/time.h"
+
+namespace content {
+
+struct BufferPresentedParams {
+ BufferPresentedParams();
+ ~BufferPresentedParams();
+
+ int32_t surface_id;
+ base::TimeTicks vsync_timebase;
+ base::TimeDelta vsync_interval;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_BUFFER_PRESENTED_PARAMS_MAC_H_
diff --git a/chromium/content/common/cache_storage/cache_storage_messages.h b/chromium/content/common/cache_storage/cache_storage_messages.h
index 277f960ee6e..82fe7552d6c 100644
--- a/chromium/content/common/cache_storage/cache_storage_messages.h
+++ b/chromium/content/common/cache_storage/cache_storage_messages.h
@@ -13,7 +13,7 @@
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
-#include "url/gurl.h"
+#include "url/origin.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -51,30 +51,30 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebServiceWorkerCacheError,
IPC_MESSAGE_CONTROL4(CacheStorageHostMsg_CacheStorageHas,
int /* thread_id */,
int /* request_id */,
- GURL /* origin */,
+ url::Origin /* origin */,
base::string16 /* fetch_store_name */)
IPC_MESSAGE_CONTROL4(CacheStorageHostMsg_CacheStorageOpen,
int /* thread_id */,
int /* request_id */,
- GURL /* origin */,
+ url::Origin /* origin */,
base::string16 /* fetch_store_name */)
IPC_MESSAGE_CONTROL4(CacheStorageHostMsg_CacheStorageDelete,
int /* thread_id */,
int /* request_id */,
- GURL /* origin */,
+ url::Origin /* origin */,
base::string16 /* fetch_store_name */)
IPC_MESSAGE_CONTROL3(CacheStorageHostMsg_CacheStorageKeys,
int /* thread_id */,
int /* request_id */,
- GURL /* origin */)
+ url::Origin /* origin */)
IPC_MESSAGE_CONTROL5(CacheStorageHostMsg_CacheStorageMatch,
int /* thread_id */,
int /* request_id */,
- GURL /* origin */,
+ url::Origin /* origin */,
content::ServiceWorkerFetchRequest,
content::CacheStorageCacheQueryParams)
diff --git a/chromium/content/common/cache_storage/cache_storage_types.cc b/chromium/content/common/cache_storage/cache_storage_types.cc
index c2e5175d693..198e6eaf300 100644
--- a/chromium/content/common/cache_storage/cache_storage_types.cc
+++ b/chromium/content/common/cache_storage/cache_storage_types.cc
@@ -13,4 +13,7 @@ CacheStorageCacheQueryParams::CacheStorageCacheQueryParams()
CacheStorageBatchOperation::CacheStorageBatchOperation() {
}
+CacheStorageBatchOperation::CacheStorageBatchOperation(
+ const CacheStorageBatchOperation& other) = default;
+
} // namespace content
diff --git a/chromium/content/common/cache_storage/cache_storage_types.h b/chromium/content/common/cache_storage/cache_storage_types.h
index bd292966c0e..22e91c0636a 100644
--- a/chromium/content/common/cache_storage/cache_storage_types.h
+++ b/chromium/content/common/cache_storage/cache_storage_types.h
@@ -39,6 +39,7 @@ enum CacheStorageCacheOperationType {
// A single batch operation for the Cache API.
struct CONTENT_EXPORT CacheStorageBatchOperation {
CacheStorageBatchOperation();
+ CacheStorageBatchOperation(const CacheStorageBatchOperation& other);
CacheStorageCacheOperationType operation_type;
ServiceWorkerFetchRequest request;
@@ -53,7 +54,9 @@ enum CacheStorageError {
CACHE_STORAGE_ERROR_EXISTS,
CACHE_STORAGE_ERROR_STORAGE,
CACHE_STORAGE_ERROR_NOT_FOUND,
- CACHE_STORAGE_ERROR_LAST = CACHE_STORAGE_ERROR_NOT_FOUND
+ CACHE_STORAGE_ERROR_QUOTA_EXCEEDED,
+ CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND,
+ CACHE_STORAGE_ERROR_LAST = CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND
};
} // namespace content
diff --git a/chromium/content/common/cc_messages.cc b/chromium/content/common/cc_messages.cc
index 70729469c7c..f5c688ebd36 100644
--- a/chromium/content/common/cc_messages.cc
+++ b/chromium/content/common/cc_messages.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <utility>
+#include "base/numerics/safe_conversions.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/filter_operations.h"
#include "cc/quads/draw_quad.h"
@@ -15,12 +16,11 @@
#include "content/public/common/common_param_traits.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkFlattenableSerialization.h"
-#include "ui/gfx/transform.h"
namespace IPC {
-void ParamTraits<cc::FilterOperation>::Write(
- Message* m, const param_type& p) {
+void ParamTraits<cc::FilterOperation>::Write(base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.type());
switch (p.type()) {
case cc::FilterOperation::GRAYSCALE:
@@ -57,7 +57,7 @@ void ParamTraits<cc::FilterOperation>::Write(
}
}
-bool ParamTraits<cc::FilterOperation>::Read(const Message* m,
+bool ParamTraits<cc::FilterOperation>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
cc::FilterOperation::FilterType type;
@@ -184,18 +184,18 @@ void ParamTraits<cc::FilterOperation>::Log(
l->append(")");
}
-void ParamTraits<cc::FilterOperations>::Write(
- Message* m, const param_type& p) {
- WriteParam(m, p.size());
+void ParamTraits<cc::FilterOperations>::Write(base::Pickle* m,
+ const param_type& p) {
+ WriteParam(m, base::checked_cast<uint32_t>(p.size()));
for (std::size_t i = 0; i < p.size(); ++i) {
WriteParam(m, p.at(i));
}
}
-bool ParamTraits<cc::FilterOperations>::Read(const Message* m,
+bool ParamTraits<cc::FilterOperations>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
- size_t count;
+ uint32_t count;
if (!ReadParam(m, iter, &count))
return false;
@@ -219,19 +219,18 @@ void ParamTraits<cc::FilterOperations>::Log(
l->append(")");
}
-void ParamTraits<skia::RefPtr<SkImageFilter> >::Write(
- Message* m, const param_type& p) {
+void ParamTraits<skia::RefPtr<SkImageFilter>>::Write(base::Pickle* m,
+ const param_type& p) {
SkImageFilter* filter = p.get();
if (filter) {
- skia::RefPtr<SkData> data =
- skia::AdoptRef(SkValidatingSerializeFlattenable(filter));
+ sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter));
m->WriteData(static_cast<const char*>(data->data()), data->size());
} else {
m->WriteData(0, 0);
}
}
-bool ParamTraits<skia::RefPtr<SkImageFilter>>::Read(const Message* m,
+bool ParamTraits<skia::RefPtr<SkImageFilter>>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
const char* data = 0;
@@ -255,55 +254,13 @@ void ParamTraits<skia::RefPtr<SkImageFilter> >::Log(
l->append(")");
}
-void ParamTraits<gfx::Transform>::Write(
- Message* m, const param_type& p) {
-#ifdef SK_MSCALAR_IS_FLOAT
- float column_major_data[16];
- p.matrix().asColMajorf(column_major_data);
-#else
- double column_major_data[16];
- p.matrix().asColMajord(column_major_data);
-#endif
- m->WriteBytes(&column_major_data, sizeof(SkMScalar) * 16);
-}
-
-bool ParamTraits<gfx::Transform>::Read(const Message* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char* column_major_data;
- if (!iter->ReadBytes(&column_major_data, sizeof(SkMScalar) * 16))
- return false;
- r->matrix().setColMajor(
- reinterpret_cast<const SkMScalar*>(column_major_data));
- return true;
-}
-
-void ParamTraits<gfx::Transform>::Log(
- const param_type& p, std::string* l) {
-#ifdef SK_MSCALAR_IS_FLOAT
- float row_major_data[16];
- p.matrix().asRowMajorf(row_major_data);
-#else
- double row_major_data[16];
- p.matrix().asRowMajord(row_major_data);
-#endif
- l->append("(");
- for (int i = 0; i < 16; ++i) {
- if (i > 0)
- l->append(", ");
- LogParam(row_major_data[i], l);
- }
- l->append(") ");
-}
-
-void ParamTraits<cc::RenderPass>::Write(
- Message* m, const param_type& p) {
+void ParamTraits<cc::RenderPass>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.id);
WriteParam(m, p.output_rect);
WriteParam(m, p.damage_rect);
WriteParam(m, p.transform_to_root_target);
WriteParam(m, p.has_transparent_background);
- WriteParam(m, p.quad_list.size());
+ WriteParam(m, base::checked_cast<uint32_t>(p.quad_list.size()));
cc::SharedQuadStateList::ConstIterator shared_quad_state_iter =
p.shared_quad_state_list.begin();
@@ -390,7 +347,7 @@ static size_t ReserveSizeForRenderPassWrite(const cc::RenderPass& p) {
}
template <typename QuadType>
-static cc::DrawQuad* ReadDrawQuad(const Message* m,
+static cc::DrawQuad* ReadDrawQuad(const base::Pickle* m,
base::PickleIterator* iter,
cc::RenderPass* render_pass) {
QuadType* quad = render_pass->CreateAndAppendDrawQuad<QuadType>();
@@ -399,7 +356,7 @@ static cc::DrawQuad* ReadDrawQuad(const Message* m,
return quad;
}
-bool ParamTraits<cc::RenderPass>::Read(const Message* m,
+bool ParamTraits<cc::RenderPass>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
cc::RenderPassId id;
@@ -407,7 +364,7 @@ bool ParamTraits<cc::RenderPass>::Read(const Message* m,
gfx::Rect damage_rect;
gfx::Transform transform_to_root_target;
bool has_transparent_background;
- size_t quad_list_size;
+ uint32_t quad_list_size;
if (!ReadParam(m, iter, &id) || !ReadParam(m, iter, &output_rect) ||
!ReadParam(m, iter, &damage_rect) ||
@@ -422,7 +379,7 @@ bool ParamTraits<cc::RenderPass>::Read(const Message* m,
transform_to_root_target,
has_transparent_background);
- for (size_t i = 0; i < quad_list_size; ++i) {
+ for (uint32_t i = 0; i < quad_list_size; ++i) {
cc::DrawQuad::Material material;
base::PickleIterator temp_iter = *iter;
if (!ReadParam(m, &temp_iter, &material))
@@ -566,7 +523,7 @@ namespace {
};
}
-void ParamTraits<cc::CompositorFrame>::Write(Message* m,
+void ParamTraits<cc::CompositorFrame>::Write(base::Pickle* m,
const param_type& p) {
WriteParam(m, p.metadata);
if (p.delegated_frame_data) {
@@ -581,7 +538,7 @@ void ParamTraits<cc::CompositorFrame>::Write(Message* m,
}
}
-bool ParamTraits<cc::CompositorFrame>::Read(const Message* m,
+bool ParamTraits<cc::CompositorFrame>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
if (!ReadParam(m, iter, &p->metadata))
@@ -622,7 +579,7 @@ void ParamTraits<cc::CompositorFrame>::Log(const param_type& p,
l->append(")");
}
-void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
+void ParamTraits<cc::CompositorFrameAck>::Write(base::Pickle* m,
const param_type& p) {
WriteParam(m, p.resources);
if (p.gl_frame_data) {
@@ -633,7 +590,7 @@ void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
}
}
-bool ParamTraits<cc::CompositorFrameAck>::Read(const Message* m,
+bool ParamTraits<cc::CompositorFrameAck>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
if (!ReadParam(m, iter, &p->resources))
@@ -667,7 +624,7 @@ void ParamTraits<cc::CompositorFrameAck>::Log(const param_type& p,
l->append(")");
}
-void ParamTraits<cc::DelegatedFrameData>::Write(Message* m,
+void ParamTraits<cc::DelegatedFrameData>::Write(base::Pickle* m,
const param_type& p) {
DCHECK_NE(0u, p.render_pass_list.size());
@@ -681,15 +638,16 @@ void ParamTraits<cc::DelegatedFrameData>::Write(Message* m,
WriteParam(m, p.device_scale_factor);
WriteParam(m, p.resource_list);
- WriteParam(m, p.render_pass_list.size());
+ WriteParam(m, base::checked_cast<uint32_t>(p.render_pass_list.size()));
for (const auto& pass : p.render_pass_list) {
- WriteParam(m, pass->quad_list.size());
- WriteParam(m, pass->shared_quad_state_list.size());
+ WriteParam(m, base::checked_cast<uint32_t>(pass->quad_list.size()));
+ WriteParam(m, base::checked_cast<uint32_t>(
+ pass->shared_quad_state_list.size()));
WriteParam(m, *pass);
}
}
-bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m,
+bool ParamTraits<cc::DelegatedFrameData>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
if (!ReadParam(m, iter, &p->device_scale_factor))
@@ -701,21 +659,23 @@ bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m,
std::set<cc::RenderPassId> pass_set;
- size_t num_render_passes;
+ uint32_t num_render_passes;
if (!ReadParam(m, iter, &p->resource_list) ||
!ReadParam(m, iter, &num_render_passes) ||
num_render_passes > kMaxRenderPasses || num_render_passes == 0)
return false;
- for (size_t i = 0; i < num_render_passes; ++i) {
- size_t quad_list_size;
- size_t shared_quad_state_list_size;
+ for (uint32_t i = 0; i < num_render_passes; ++i) {
+ uint32_t quad_list_size;
+ uint32_t shared_quad_state_list_size;
if (!ReadParam(m, iter, &quad_list_size) ||
!ReadParam(m, iter, &shared_quad_state_list_size) ||
quad_list_size > kMaxQuadListSize ||
shared_quad_state_list_size > kMaxSharedQuadStateListSize)
return false;
scoped_ptr<cc::RenderPass> render_pass =
- cc::RenderPass::Create(shared_quad_state_list_size, quad_list_size);
+ cc::RenderPass::Create(
+ static_cast<size_t>(shared_quad_state_list_size),
+ static_cast<size_t>(quad_list_size));
if (!ReadParam(m, iter, render_pass.get()))
return false;
// Validate that each RenderPassDrawQuad points at a valid RenderPass
@@ -748,7 +708,7 @@ void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p,
l->append("])");
}
-void ParamTraits<cc::DrawQuad::Resources>::Write(Message* m,
+void ParamTraits<cc::DrawQuad::Resources>::Write(base::Pickle* m,
const param_type& p) {
DCHECK_LE(p.count, cc::DrawQuad::Resources::kMaxResourceIdCount);
WriteParam(m, p.count);
@@ -756,7 +716,7 @@ void ParamTraits<cc::DrawQuad::Resources>::Write(Message* m,
WriteParam(m, p.ids[i]);
}
-bool ParamTraits<cc::DrawQuad::Resources>::Read(const Message* m,
+bool ParamTraits<cc::DrawQuad::Resources>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
if (!ReadParam(m, iter, &p->count))
@@ -789,7 +749,7 @@ void ParamTraits<cc::DrawQuad::Resources>::Log(const param_type& p,
}
void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Write(
- Message* m,
+ base::Pickle* m,
const param_type& p) {
for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) {
WriteParam(m, p.size_in_pixels[i]);
@@ -797,7 +757,7 @@ void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Write(
}
bool ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) {
@@ -820,7 +780,7 @@ void ParamTraits<cc::StreamVideoDrawQuad::OverlayResources>::Log(
}
void ParamTraits<cc::TextureDrawQuad::OverlayResources>::Write(
- Message* m,
+ base::Pickle* m,
const param_type& p) {
for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) {
WriteParam(m, p.size_in_pixels[i]);
@@ -828,7 +788,7 @@ void ParamTraits<cc::TextureDrawQuad::OverlayResources>::Write(
}
bool ParamTraits<cc::TextureDrawQuad::OverlayResources>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
for (size_t i = 0; i < cc::DrawQuad::Resources::kMaxResourceIdCount; ++i) {
diff --git a/chromium/content/common/cc_messages.h b/chromium/content/common/cc_messages.h
index 9f2e84ece39..0a6c213ae98 100644
--- a/chromium/content/common/cc_messages.h
+++ b/chromium/content/common/cc_messages.h
@@ -28,9 +28,10 @@
#include "cc/surfaces/surface_id.h"
#include "cc/surfaces/surface_sequence.h"
#include "content/common/content_export.h"
-#include "gpu/ipc/gpu_command_buffer_traits.h"
+#include "gpu/ipc/common/gpu_command_buffer_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
#ifndef CONTENT_COMMON_CC_MESSAGES_H_
#define CONTENT_COMMON_CC_MESSAGES_H_
@@ -48,88 +49,100 @@ namespace IPC {
template <>
struct ParamTraits<cc::FilterOperation> {
typedef cc::FilterOperation param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<cc::FilterOperations> {
typedef cc::FilterOperations param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<skia::RefPtr<SkImageFilter> > {
typedef skia::RefPtr<SkImageFilter> param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct ParamTraits<gfx::Transform> {
- typedef gfx::Transform param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<cc::RenderPass> {
typedef cc::RenderPass param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template<>
struct CONTENT_EXPORT ParamTraits<cc::CompositorFrame> {
typedef cc::CompositorFrame param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
template<>
struct CONTENT_EXPORT ParamTraits<cc::CompositorFrameAck> {
typedef cc::CompositorFrameAck param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
template<>
struct CONTENT_EXPORT ParamTraits<cc::DelegatedFrameData> {
typedef cc::DelegatedFrameData param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<cc::DrawQuad::Resources> {
typedef cc::DrawQuad::Resources param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<cc::StreamVideoDrawQuad::OverlayResources> {
typedef cc::StreamVideoDrawQuad::OverlayResources param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<cc::TextureDrawQuad::OverlayResources> {
typedef cc::TextureDrawQuad::OverlayResources param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
static void Log(const param_type& p, std::string* l);
};
@@ -246,6 +259,8 @@ IPC_STRUCT_TRAITS_BEGIN(cc::YUVVideoDrawQuad)
IPC_STRUCT_TRAITS_MEMBER(ya_tex_size)
IPC_STRUCT_TRAITS_MEMBER(uv_tex_size)
IPC_STRUCT_TRAITS_MEMBER(color_space)
+ IPC_STRUCT_TRAITS_MEMBER(resource_offset)
+ IPC_STRUCT_TRAITS_MEMBER(resource_multiplier)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::SharedQuadState)
diff --git a/chromium/content/common/cc_messages_unittest.cc b/chromium/content/common/cc_messages_unittest.cc
index 799c39ff450..423bfffaa6b 100644
--- a/chromium/content/common/cc_messages_unittest.cc
+++ b/chromium/content/common/cc_messages_unittest.cc
@@ -433,7 +433,7 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_rect1_inside_rect1, arbitrary_bool1, arbitrary_rectf1,
arbitrary_rectf2, arbitrary_size1, arbitrary_size2, arbitrary_resourceid1,
arbitrary_resourceid2, arbitrary_resourceid3, arbitrary_resourceid4,
- arbitrary_color_space);
+ arbitrary_color_space, arbitrary_float1, arbitrary_float2);
pass_cmp->CopyFromAndAppendDrawQuad(yuvvideo_in,
yuvvideo_in->shared_quad_state);
@@ -617,8 +617,14 @@ TEST_F(CCMessagesTest, UnusedSharedQuadStates) {
TEST_F(CCMessagesTest, Resources) {
IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
gfx::Size arbitrary_size(757, 1281);
- gpu::SyncToken arbitrary_token1(71234838);
- gpu::SyncToken arbitrary_token2(53589793);
+ gpu::SyncToken arbitrary_token1(gpu::CommandBufferNamespace::GPU_IO, 0,
+ gpu::CommandBufferId::FromUnsafeValue(0x123),
+ 71234838);
+ arbitrary_token1.SetVerifyFlush();
+ gpu::SyncToken arbitrary_token2(gpu::CommandBufferNamespace::GPU_IO, 0,
+ gpu::CommandBufferId::FromUnsafeValue(0x123),
+ 53589793);
+ arbitrary_token2.SetVerifyFlush();
GLbyte arbitrary_mailbox1[GL_MAILBOX_SIZE_CHROMIUM] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
diff --git a/chromium/content/common/child_process_host_impl.cc b/chromium/content/common/child_process_host_impl.cc
index d69d5352a28..1aa93b52987 100644
--- a/chromium/content/common/child_process_host_impl.cc
+++ b/chromium/content/common/child_process_host_impl.cc
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/hash.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/numerics/safe_math.h"
#include "base/path_service.h"
@@ -21,10 +22,10 @@
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "build/build_config.h"
#include "content/common/child_process_messages.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
#include "content/public/common/child_process_host_delegate.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
+#include "gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h"
#include "ipc/attachment_broker.h"
#include "ipc/attachment_broker_privileged.h"
#include "ipc/ipc_channel.h"
@@ -88,7 +89,7 @@ ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
#endif
#if USE_ATTACHMENT_BROKER
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if defined(OS_MACOSX)
// On Mac, the privileged AttachmentBroker needs a reference to the Mach port
// Provider, which is only available in the chrome/ module. The attachment
// broker must already be created.
@@ -97,7 +98,7 @@ ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
// Construct the privileged attachment broker early in the life cycle of a
// child process.
IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+#endif // defined(OS_MACOSX)
#endif // USE_ATTACHMENT_BROKER
}
@@ -132,12 +133,17 @@ void ChildProcessHostImpl::ForceShutdown() {
std::string ChildProcessHostImpl::CreateChannel() {
channel_id_ = IPC::Channel::GenerateVerifiedChannelID(std::string());
channel_ = IPC::Channel::CreateServer(channel_id_, this);
- if (!channel_->Connect())
- return std::string();
#if USE_ATTACHMENT_BROKER
IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
- channel_.get());
+ channel_.get(), base::MessageLoopForIO::current()->task_runner());
+#endif
+ if (!channel_->Connect()) {
+#if USE_ATTACHMENT_BROKER
+ IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
+ channel_.get());
#endif
+ return std::string();
+ }
for (size_t i = 0; i < filters_.size(); ++i)
filters_[i]->OnFilterAdded(channel_.get());
@@ -316,8 +322,8 @@ void ChildProcessHostImpl::OnAllocateGpuMemoryBuffer(
// AllocateForChildProcess() will check if |width| and |height| are valid
// and handle failure in a controlled way when not. We just need to make
// sure |usage| is supported here.
- if (GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage)) {
- *handle = GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
+ if (gpu::GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage)) {
+ *handle = gpu::GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
id, gfx::Size(width, height), format, peer_process_.Handle());
}
}
diff --git a/chromium/content/common/child_process_messages.h b/chromium/content/common/child_process_messages.h
index b4ee49f122d..fd5fac49351 100644
--- a/chromium/content/common/child_process_messages.h
+++ b/chromium/content/common/child_process_messages.h
@@ -16,12 +16,20 @@
#include "build/build_config.h"
#include "cc/resources/shared_bitmap_manager.h"
#include "content/common/content_export.h"
+#include "content/common/content_param_traits_macros.h"
+#include "content/common/gpu_process_launch_causes.h"
#include "content/common/host_discardable_shared_memory_manager.h"
#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/ipc/common/gpu_param_traits_macros.h"
+#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
+
+IPC_ENUM_TRAITS_MAX_VALUE(content::CauseForGpuLaunch,
+ content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM - 1)
IPC_ENUM_TRAITS_MAX_VALUE(tracked_objects::ThreadData::Status,
tracked_objects::ThreadData::STATUS_LAST)
@@ -62,26 +70,6 @@ IPC_STRUCT_TRAITS_BEGIN(tracked_objects::ProcessDataSnapshot)
IPC_STRUCT_TRAITS_MEMBER(process_id)
IPC_STRUCT_TRAITS_END()
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuMemoryBufferType,
- gfx::GPU_MEMORY_BUFFER_TYPE_LAST)
-
-IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferHandle)
- IPC_STRUCT_TRAITS_MEMBER(id)
- IPC_STRUCT_TRAITS_MEMBER(type)
- IPC_STRUCT_TRAITS_MEMBER(handle)
- IPC_STRUCT_TRAITS_MEMBER(offset)
- IPC_STRUCT_TRAITS_MEMBER(stride)
-#if defined(USE_OZONE)
- IPC_STRUCT_TRAITS_MEMBER(native_pixmap_handle)
-#elif defined(OS_MACOSX)
- IPC_STRUCT_TRAITS_MEMBER(mach_port)
-#endif
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gfx::GpuMemoryBufferId)
- IPC_STRUCT_TRAITS_MEMBER(id)
-IPC_STRUCT_TRAITS_END()
-
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -114,8 +102,16 @@ IPC_MESSAGE_CONTROL2(ChildProcessMsg_GetChildProfilerData,
IPC_MESSAGE_CONTROL1(ChildProcessMsg_ProfilingPhaseCompleted,
int /* profiling_phase */)
+// Sent to set the shared memory buffer to be used for storing histograms that
+// are to be reported by the browser process to UMA. The following message
+// (GetChildNonPersistentHistogramData) will return any histograms created
+// before this message is received but not any histograms created afterward.
+IPC_MESSAGE_CONTROL2(ChildProcessMsg_SetHistogramMemory,
+ base::SharedMemoryHandle /* shm_handle */,
+ int /* shm_size */)
+
// Send to all the child processes to send back histogram data.
-IPC_MESSAGE_CONTROL1(ChildProcessMsg_GetChildHistogramData,
+IPC_MESSAGE_CONTROL1(ChildProcessMsg_GetChildNonPersistentHistogramData,
int /* sequence_number */)
// Sent to child processes to tell them to enter or leave background mode.
@@ -126,15 +122,22 @@ IPC_MESSAGE_CONTROL1(ChildProcessMsg_SetProcessBackgrounded,
IPC_MESSAGE_CONTROL1(ChildProcessMsg_SetMojoParentPipeHandle,
IPC::PlatformFileForTransit /* handle */)
-#if defined(USE_OZONE)
-// Sent to child processes to initialize ClientNativePixmapFactory using
-// a device file descriptor.
-IPC_MESSAGE_CONTROL1(ChildProcessMsg_InitializeClientNativePixmapFactory,
- base::FileDescriptor /* device_fd */)
-#endif
////////////////////////////////////////////////////////////////////////////////
// Messages sent from the child process to the browser.
+// A renderer sends this when it wants to create a connection to the GPU
+// process. The browser will create the GPU process if necessary, and will
+// return a handle to the channel via a GpuChannelEstablished message.
+IPC_SYNC_MESSAGE_CONTROL1_3(ChildProcessHostMsg_EstablishGpuChannel,
+ content::CauseForGpuLaunch,
+ int /* client id */,
+ IPC::ChannelHandle /* handle to channel */,
+ gpu::GPUInfo /* stats about GPU process*/)
+
+// A renderer sends this when it wants to know whether a gpu process exists.
+IPC_SYNC_MESSAGE_CONTROL0_1(ChildProcessHostMsg_HasGpuProcess,
+ bool /* result */)
+
IPC_MESSAGE_CONTROL0(ChildProcessHostMsg_ShutdownRequest)
// Send back profiler data (ThreadData in tracked_objects).
diff --git a/chromium/content/common/child_process_sandbox_support_impl_linux.h b/chromium/content/common/child_process_sandbox_support_impl_linux.h
index 97221f6e838..e2e973d9771 100644
--- a/chromium/content/common/child_process_sandbox_support_impl_linux.h
+++ b/chromium/content/common/child_process_sandbox_support_impl_linux.h
@@ -30,8 +30,9 @@ void GetFallbackFontForCharacter(const int32_t character,
// |size_and_style| stores the bold setting in its least-significant bit, the
// italic setting in its second-least-significant bit, and holds the requested
// size in pixels into its remaining bits.
-// TODO(derat): Update WebSandboxSupport's getRenderStyleForStrike() method to
-// pass the style and size separately instead of packing them into an int.
+// TODO(derat): Update WebSandboxSupport's getWebFontRenderStyleForStrike()
+// method to pass the style and size separately instead of packing them into an
+// int.
void GetRenderStyleForStrike(const char* family,
int size_and_style,
blink::WebFontRenderStyle* out);
diff --git a/chromium/content/common/clipboard_messages.h b/chromium/content/common/clipboard_messages.h
index 00a198c1f6a..36877f0a241 100644
--- a/chromium/content/common/clipboard_messages.h
+++ b/chromium/content/common/clipboard_messages.h
@@ -10,13 +10,16 @@
#include <string>
#include <vector>
+#include "build/build_config.h"
#include "base/memory/shared_memory.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "content/common/clipboard_format.h"
-#include "content/public/common/common_param_traits.h"
+#include "content/common/content_export.h"
#include "ipc/ipc_message_macros.h"
+#include "ipc/param_traits_macros.h"
#include "ui/base/clipboard/clipboard.h"
+#include "url/ipc/url_param_traits.h"
// Singly-included section for types and/or struct declarations.
#ifndef CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
diff --git a/chromium/content/common/common.sb b/chromium/content/common/common.sb
index 1d9a8ac1c89..49c654c35fd 100644
--- a/chromium/content/common/common.sb
+++ b/chromium/content/common/common.sb
@@ -16,7 +16,6 @@
; Define constants for all of the parameter strings passed in.
(define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING")
(define enable-logging "ENABLE_LOGGING")
-(define component-build-workaround "COMPONENT_BUILD_WORKAROUND")
(define permitted-dir "PERMITTED_DIR")
(define homedir-as-literal "USER_HOMEDIR_AS_LITERAL")
(define lion-or-later "LION_OR_LATER")
@@ -50,9 +49,3 @@
; Allow direct access to /dev/urandom, similar to Linux/POSIX, to allow
; third party code (eg: bits of Adobe Flash and NSS) to function properly.
(allow file-read-data file-read-metadata (literal "/dev/urandom"))
-
-; Enables reading file metadata for the Chrome bundle and its parent paths.
-; https://crbug.com/127465
-(if (and (param-defined? component-build-workaround)
- (param-true? component-build-workaround))
- (allow file-read-metadata ))
diff --git a/chromium/content/common/common_param_traits_unittest.cc b/chromium/content/common/common_param_traits_unittest.cc
index 03c19a08731..546834bd9fb 100644
--- a/chromium/content/common/common_param_traits_unittest.cc
+++ b/chromium/content/common/common_param_traits_unittest.cc
@@ -20,68 +20,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "url/gurl.h"
-
-// Tests that serialize/deserialize correctly understand each other
-TEST(IPCMessageTest, Serialize) {
- const char* serialize_cases[] = {
- "http://www.google.com/",
- "http://user:pass@host.com:888/foo;bar?baz#nop",
- };
-
- for (size_t i = 0; i < arraysize(serialize_cases); i++) {
- GURL input(serialize_cases[i]);
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<GURL>::Write(&msg, input);
-
- GURL output;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(IPC::ParamTraits<GURL>::Read(&msg, &iter, &output));
-
- // We want to test each component individually to make sure its range was
- // correctly serialized and deserialized, not just the spec.
- EXPECT_EQ(input.possibly_invalid_spec(), output.possibly_invalid_spec());
- EXPECT_EQ(input.is_valid(), output.is_valid());
- EXPECT_EQ(input.scheme(), output.scheme());
- EXPECT_EQ(input.username(), output.username());
- EXPECT_EQ(input.password(), output.password());
- EXPECT_EQ(input.host(), output.host());
- EXPECT_EQ(input.port(), output.port());
- EXPECT_EQ(input.path(), output.path());
- EXPECT_EQ(input.query(), output.query());
- EXPECT_EQ(input.ref(), output.ref());
- }
-
- // Test an excessively long GURL.
- {
- const std::string url = std::string("http://example.org/").append(
- content::kMaxURLChars + 1, 'a');
- GURL input(url.c_str());
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- IPC::ParamTraits<GURL>::Write(&msg, input);
-
- GURL output;
- base::PickleIterator iter(msg);
- EXPECT_TRUE(IPC::ParamTraits<GURL>::Read(&msg, &iter, &output));
- EXPECT_TRUE(output.is_empty());
- }
-
- // Test an invalid GURL.
- {
- IPC::Message msg;
- msg.WriteString("#inva://idurl/");
- GURL output;
- base::PickleIterator iter(msg);
- EXPECT_FALSE(IPC::ParamTraits<GURL>::Read(&msg, &iter, &output));
- }
-
- // Also test the corrupt case.
- IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
- msg.WriteInt(99);
- GURL output;
- base::PickleIterator iter(msg);
- EXPECT_FALSE(IPC::ParamTraits<GURL>::Read(&msg, &iter, &output));
-}
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
// Tests std::pair serialization
TEST(IPCMessageTest, Pair) {
diff --git a/chromium/content/common/content_constants_internal.cc b/chromium/content/common/content_constants_internal.cc
index 7b8b68ae3f7..ec623ac2c4b 100644
--- a/chromium/content/common/content_constants_internal.cc
+++ b/chromium/content/common/content_constants_internal.cc
@@ -18,16 +18,11 @@ const int64_t kHungRendererDelayMs = 30000;
const int64_t kNewContentRenderingDelayMs = 4000;
-const uint16_t kMaxPluginSideLength = 1 << 15;
-// 8m pixels.
-const uint32_t kMaxPluginSize = 8 << 20;
-
// 20MiB
const size_t kMaxLengthOfDataURLString = 1024 * 1024 * 20;
const int kTraceEventBrowserProcessSortIndex = -6;
const int kTraceEventRendererProcessSortIndex = -5;
-const int kTraceEventPluginProcessSortIndex = -4;
const int kTraceEventPpapiProcessSortIndex = -3;
const int kTraceEventPpapiBrokerProcessSortIndex = -2;
const int kTraceEventGpuProcessSortIndex = -1;
diff --git a/chromium/content/common/content_constants_internal.h b/chromium/content/common/content_constants_internal.h
index 46f351b401c..a3584b0d8b4 100644
--- a/chromium/content/common/content_constants_internal.h
+++ b/chromium/content/common/content_constants_internal.h
@@ -19,19 +19,12 @@ CONTENT_EXPORT extern const int64_t kHungRendererDelayMs;
// before clearing previously displayed graphics.
extern const int64_t kNewContentRenderingDelayMs;
-// The maximum plugin width and height.
-extern const uint16_t kMaxPluginSideLength;
-// The maximum plugin size, defined as the number of pixels occupied by the
-// plugin.
-extern const uint32_t kMaxPluginSize;
-
// The maximum length of string as data url.
extern const size_t kMaxLengthOfDataURLString;
// Constants used to organize content processes in about:tracing.
CONTENT_EXPORT extern const int kTraceEventBrowserProcessSortIndex;
CONTENT_EXPORT extern const int kTraceEventRendererProcessSortIndex;
-CONTENT_EXPORT extern const int kTraceEventPluginProcessSortIndex;
CONTENT_EXPORT extern const int kTraceEventPpapiProcessSortIndex;
CONTENT_EXPORT extern const int kTraceEventPpapiBrokerProcessSortIndex;
CONTENT_EXPORT extern const int kTraceEventGpuProcessSortIndex;
diff --git a/chromium/content/common/content_message_generator.h b/chromium/content/common/content_message_generator.h
index 3d49ab228a3..c26352d010c 100644
--- a/chromium/content/common/content_message_generator.h
+++ b/chromium/content/common/content_message_generator.h
@@ -28,7 +28,7 @@
#include "content/common/frame_messages.h"
#include "content/common/gamepad_messages.h"
#include "content/common/geofencing_messages.h"
-#include "content/common/gpu/gpu_messages.h"
+#include "content/common/gpu_host_messages.h"
#include "content/common/indexed_db/indexed_db_messages.h"
#include "content/common/input_messages.h"
#include "content/common/manifest_manager_messages.h"
@@ -36,20 +36,20 @@
#include "content/common/media/audio_messages.h"
// TODO(xhwang): Move this to a new ifdef block.
#include "content/common/media/cdm_messages.h"
+#include "content/common/media/media_player_delegate_messages.h"
#include "content/common/media/media_stream_messages.h"
#include "content/common/media/media_stream_track_metrics_host_messages.h"
#include "content/common/media/midi_messages.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/common/media/video_capture_messages.h"
#include "content/common/media/webrtc_identity_messages.h"
-#include "content/common/memory_benchmark_messages.h"
#include "content/common/memory_messages.h"
#include "content/common/message_port_messages.h"
#include "content/common/mime_registry_messages.h"
#include "content/common/mojo/mojo_messages.h"
+#include "content/common/page_messages.h"
#include "content/common/pepper_messages.h"
#include "content/common/platform_notification_messages.h"
-#include "content/common/plugin_process_messages.h"
#include "content/common/power_monitor_messages.h"
#include "content/common/push_messaging_messages.h"
#include "content/common/quota_messages.h"
@@ -74,6 +74,7 @@
#include "content/common/gin_java_bridge_messages.h"
#include "content/common/media/media_player_messages_android.h"
#include "content/common/media/media_session_messages_android.h"
+#include "content/common/media/surface_view_manager_messages_android.h"
#endif // defined(OS_ANDROID)
#if defined(OS_WIN)
diff --git a/chromium/content/common/content_param_traits.cc b/chromium/content/common/content_param_traits.cc
index 0c60380e281..07e1a239bfd 100644
--- a/chromium/content/common/content_param_traits.cc
+++ b/chromium/content/common/content_param_traits.cc
@@ -12,11 +12,12 @@
namespace IPC {
-void ParamTraits<WebInputEventPointer>::Write(Message* m, const param_type& p) {
+void ParamTraits<WebInputEventPointer>::Write(base::Pickle* m,
+ const param_type& p) {
m->WriteData(reinterpret_cast<const char*>(p), p->size);
}
-bool ParamTraits<WebInputEventPointer>::Read(const Message* m,
+bool ParamTraits<WebInputEventPointer>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
const char* data;
diff --git a/chromium/content/common/content_param_traits.h b/chromium/content/common/content_param_traits.h
index e90a14bd05c..61107aa06e1 100644
--- a/chromium/content/common/content_param_traits.h
+++ b/chromium/content/common/content_param_traits.h
@@ -27,12 +27,10 @@ namespace IPC {
template <>
struct ParamTraits<content::WebCursor> {
typedef content::WebCursor param_type;
- static void Write(Message* m, const param_type& p) {
- p.Serialize(m);
- }
- static bool Read(const Message* m,
+ static void Write(base::Pickle* m, const param_type& p) { p.Serialize(m); }
+ static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
- param_type* r) {
+ param_type* r) {
return r->Deserialize(iter);
}
static void Log(const param_type& p, std::string* l) {
@@ -44,9 +42,11 @@ typedef const blink::WebInputEvent* WebInputEventPointer;
template <>
struct ParamTraits<WebInputEventPointer> {
typedef WebInputEventPointer param_type;
- static void Write(Message* m, const param_type& p);
+ static void Write(base::Pickle* m, const param_type& p);
// Note: upon read, the event has the lifetime of the message.
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
diff --git a/chromium/content/common/content_param_traits_macros.h b/chromium/content/common/content_param_traits_macros.h
index 762436de718..753947bf530 100644
--- a/chromium/content/common/content_param_traits_macros.h
+++ b/chromium/content/common/content_param_traits_macros.h
@@ -14,11 +14,13 @@
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/public/platform/WebAddressSpace.h"
#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "third_party/WebKit/public/web/WebContentSecurityPolicy.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h"
+#include "ui/gfx/gpu_memory_buffer.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -33,6 +35,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(content::RequestContextFrameType,
content::REQUEST_CONTEXT_FRAME_TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContentSecurityPolicyType,
blink::WebContentSecurityPolicyTypeLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebAddressSpace, blink::WebAddressSpaceLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebSharedWorkerCreationContextType,
blink::WebSharedWorkerCreationContextTypeLast)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebInputEvent::Type,
diff --git a/chromium/content/common/content_switches_internal.cc b/chromium/content/common/content_switches_internal.cc
index f496c504f59..d0d5ec7e933 100644
--- a/chromium/content/common/content_switches_internal.cc
+++ b/chromium/content/common/content_switches_internal.cc
@@ -20,9 +20,9 @@ namespace content {
namespace {
-#if defined(OS_WIN)
-static bool g_win32k_renderer_lockdown_disabled = false;
-#endif
+bool IsUseZoomForDSFEnabledByDefault() {
+ return false;
+}
} // namespace
@@ -30,29 +30,13 @@ bool IsPinchToZoomEnabled() {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- // --disable-pinch should always disable pinch
- if (command_line.HasSwitch(switches::kDisablePinch))
- return false;
-
-#if defined(OS_WIN)
- return base::win::GetVersion() >= base::win::VERSION_WIN8;
-#elif defined(OS_CHROMEOS)
- return true;
-#else
- return command_line.HasSwitch(switches::kEnableViewport) ||
- command_line.HasSwitch(switches::kEnablePinch);
-#endif
+ // Enable pinch everywhere unless it's been explicitly disabled.
+ return !command_line.HasSwitch(switches::kDisablePinch);
}
#if defined(OS_WIN)
-void DisableWin32kRendererLockdown() {
- g_win32k_renderer_lockdown_disabled = true;
-}
-
bool IsWin32kRendererLockdownEnabled() {
- if (g_win32k_renderer_lockdown_disabled)
- return false;
if (base::win::GetVersion() < base::win::VERSION_WIN8)
return false;
if (!gfx::win::ShouldUseDirectWrite())
@@ -84,8 +68,15 @@ V8CacheOptions GetV8CacheOptions() {
}
bool IsUseZoomForDSFEnabled() {
- static bool enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableUseZoomForDSF);
+ static bool use_zoom_for_dsf_enabled_by_default =
+ IsUseZoomForDSFEnabledByDefault();
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ bool enabled =
+ (command_line->HasSwitch(switches::kEnableUseZoomForDSF) ||
+ use_zoom_for_dsf_enabled_by_default) &&
+ command_line->GetSwitchValueASCII(
+ switches::kEnableUseZoomForDSF) != "false";
+
return enabled;
}
diff --git a/chromium/content/common/content_switches_internal.h b/chromium/content/common/content_switches_internal.h
index 990070c4ccd..aacd9426e58 100644
--- a/chromium/content/common/content_switches_internal.h
+++ b/chromium/content/common/content_switches_internal.h
@@ -6,21 +6,19 @@
#define CONTENT_COMMON_CONTENT_SWITCHES_INTERNAL_H_
#include "build/build_config.h"
+#include "content/common/content_export.h"
#include "content/public/common/web_preferences.h"
namespace content {
bool IsPinchToZoomEnabled();
#if defined(OS_WIN)
-// Disables Win32k Renderer lockdown for any future renderer child processes.
-void DisableWin32kRendererLockdown();
-
// Returns whether Win32k Renderer lockdown is enabled or not.
bool IsWin32kRendererLockdownEnabled();
#endif
V8CacheOptions GetV8CacheOptions();
-bool IsUseZoomForDSFEnabled();
+CONTENT_EXPORT bool IsUseZoomForDSFEnabled();
} // namespace content
diff --git a/chromium/content/common/database_identifier_unittest.cc b/chromium/content/common/database_identifier_unittest.cc
index f866b7639ef..dac125a9bba 100644
--- a/chromium/content/common/database_identifier_unittest.cc
+++ b/chromium/content/common/database_identifier_unittest.cc
@@ -35,6 +35,9 @@ TEST(DatabaseIdentifierTest, CreateIdentifierFromOrigin) {
{"data:", "__0"},
{"about:blank", "__0"},
{"non-standard://foobar.com", "__0"},
+ {"http://[::1]:8080", "http_[__1]_8080"},
+ {"http://[3ffe:2a00:100:7031::1]", "http_[3ffe_2a00_100_7031__1]_0"},
+ {"http://[::ffff:8190:3426]", "http_[__ffff_8190_3426]_0"},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
@@ -203,6 +206,13 @@ TEST(DatabaseIdentifierTest, ExtractOriginDataFromIdentifier) {
{"http_dot.com_0", "http", "dot.com", 0, GURL("http://dot.com"), false},
{"http_escaped%3Dfun.com_0", "http", "escaped%3dfun.com", 0,
GURL("http://escaped%3dfun.com"), false},
+ {"http_[__1]_8080",
+ "http", "[::1]", 8080, GURL("http://[::1]:8080"), false},
+ {"http_[3ffe_2a00_100_7031__1]_0",
+ "http", "[3ffe:2a00:100:7031::1]", 0,
+ GURL("http://[3ffe:2a00:100:7031::1]"), false},
+ {"http_[__ffff_8190_3426]_0",
+ "http", "[::ffff:8190:3426]", 0, GURL("http://[::ffff:8190:3426]"), false},
};
for (size_t i = 0; i < arraysize(valid_cases); ++i) {
@@ -245,5 +255,33 @@ TEST(DatabaseIdentifierTest, ExtractOriginDataFromIdentifier) {
}
}
+static GURL ToAndFromOriginIdentifier(const GURL origin_url) {
+ std::string id = storage::GetIdentifierFromOrigin(origin_url);
+ return storage::GetOriginFromIdentifier(id);
+}
+
+static void TestValidOriginIdentifier(bool expected_result,
+ const std::string& id) {
+ EXPECT_EQ(expected_result,
+ storage::IsValidOriginIdentifier(id));
+}
+
+TEST(DatabaseIdentifierTest, OriginIdentifiers) {
+ const GURL kFileOrigin(GURL("file:///").GetOrigin());
+ const GURL kHttpOrigin(GURL("http://bar/").GetOrigin());
+ EXPECT_EQ(kFileOrigin, ToAndFromOriginIdentifier(kFileOrigin));
+ EXPECT_EQ(kHttpOrigin, ToAndFromOriginIdentifier(kHttpOrigin));
+}
+
+TEST(DatabaseIdentifierTest, IsValidOriginIdentifier) {
+ TestValidOriginIdentifier(true, "http_bar_0");
+ TestValidOriginIdentifier(false, "");
+ TestValidOriginIdentifier(false, "bad..id");
+ TestValidOriginIdentifier(false, "bad/id");
+ TestValidOriginIdentifier(false, "bad\\id");
+ TestValidOriginIdentifier(false, "http_bad:0_2");
+ TestValidOriginIdentifier(false, std::string("bad\0id", 6));
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/common/devtools_messages.h b/chromium/content/common/devtools_messages.h
index 7edc617df96..4c7c24a089d 100644
--- a/chromium/content/common/devtools_messages.h
+++ b/chromium/content/common/devtools_messages.h
@@ -43,7 +43,6 @@
#include <string>
#include "content/common/content_export.h"
-#include "content/public/common/common_param_traits.h"
#include "content/public/common/console_message_level.h"
#include "ipc/ipc_message_macros.h"
@@ -103,6 +102,19 @@ IPC_MESSAGE_ROUTED2(DevToolsAgentMsg_InspectElement,
int /* x */,
int /* y */)
+// ACK for DevToolsAgentHostMsg_RequestNewWindow message.
+IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_RequestNewWindow_ACK,
+ bool /* success */)
+
+//-----------------------------------------------------------------------------
+// These are messages sent from renderer's DevToolsAgent to browser.
+
+// Requests new DevTools window being opened for frame in the same process
+// with given routing id.
+IPC_MESSAGE_ROUTED1(DevToolsAgentHostMsg_RequestNewWindow,
+ int /* frame_route_id */)
+
+
//-----------------------------------------------------------------------------
// These are messages sent from the browser to the renderer.
diff --git a/chromium/content/common/discardable_shared_memory_heap.cc b/chromium/content/common/discardable_shared_memory_heap.cc
index 263f83b24ad..3e39216cbc1 100644
--- a/chromium/content/common/discardable_shared_memory_heap.cc
+++ b/chromium/content/common/discardable_shared_memory_heap.cc
@@ -418,12 +418,14 @@ void DiscardableSharedMemoryHeap::OnMemoryDump(
// to avoid double-counting segments when both browser and child process emit
// them. In the special case of single-process-mode, this will be the only
// dumper active and the single ownership edge will become a no-op in the UI.
+ // The global dump is created as a weak dump so that the segment is removed if
+ // the browser does not dump it (segment was purged).
const uint64_t tracing_process_id =
base::trace_event::MemoryDumpManager::GetInstance()
->GetTracingProcessId();
base::trace_event::MemoryAllocatorDumpGuid shared_segment_guid =
GetSegmentGUIDForTracing(tracing_process_id, segment_id);
- pmd->CreateSharedGlobalAllocatorDump(shared_segment_guid);
+ pmd->CreateWeakSharedGlobalAllocatorDump(shared_segment_guid);
// The size is added to the global dump so that it gets propagated to both the
// dumps associated.
diff --git a/chromium/content/common/dom_storage/dom_storage_messages.h b/chromium/content/common/dom_storage/dom_storage_messages.h
index 7fd4426a766..59d22c9641b 100644
--- a/chromium/content/common/dom_storage/dom_storage_messages.h
+++ b/chromium/content/common/dom_storage/dom_storage_messages.h
@@ -7,11 +7,11 @@
#include <stdint.h>
#include "content/common/dom_storage/dom_storage_types.h"
-#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "third_party/WebKit/public/platform/WebStorageArea.h"
#include "url/gurl.h"
+#include "url/ipc/url_param_traits.h"
#define IPC_MESSAGE_START DOMStorageMsgStart
diff --git a/chromium/content/common/drag_messages.h b/chromium/content/common/drag_messages.h
index 455bbffa067..8d2fd772370 100644
--- a/chromium/content/common/drag_messages.h
+++ b/chromium/content/common/drag_messages.h
@@ -6,7 +6,6 @@
// Multiply-included message file, hence no include guard.
#include "content/common/drag_event_source_info.h"
-#include "content/public/common/common_param_traits.h"
#include "content/public/common/drop_data.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/web/WebDragOperation.h"
diff --git a/chromium/content/common/dwrite_font_platform_win.cc b/chromium/content/common/dwrite_font_platform_win.cc
deleted file mode 100644
index 56140f421aa..00000000000
--- a/chromium/content/common/dwrite_font_platform_win.cc
+++ /dev/null
@@ -1,1282 +0,0 @@
-// Copyright 2014 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 "content/public/common/dwrite_font_platform_win.h"
-
-#include <windows.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <dwrite.h>
-#include <wrl/implements.h>
-#include <wrl/wrappers/corewrappers.h>
-
-#include <limits>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/command_line.h"
-#include "base/debug/alias.h"
-#include "base/debug/crash_logging.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/path_service.h"
-#include "base/process/process_handle.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "base/win/registry.h"
-#include "base/win/scoped_comptr.h"
-#include "content/public/common/content_switches.h"
-
-namespace {
-
-// Font Cache implementation short story:
-// Due to our sandboxing restrictions, we cannot connect to Windows font cache
-// service from Renderer and need to use DirectWrite isolated font loading
-// mechanism.
-// DirectWrite needs to be initialized before any of the API could be used.
-// During initialization DirectWrite loads all font files and populates
-// internal cache, we refer this phase as enumeration and we are trying
-// to optimize this phase in our cache approach. Using cache during
-// initialization will help improve on startup latency in each renderer
-// instance.
-// During enumeration DirectWrite reads various fragments from .ttf/.ttc
-// font files. Our assumption is that these fragments are being read to
-// cache information such as font families, supported sizes etc.
-// For reading fragments DirectWrite calls ReadFragment of our FontFileStream
-// implementation with parameters start_offset and length. We cache these
-// parameters along with associated data chunk.
-// Here is small example of how segments are read
-// start_offset: 0, length: 16
-// start_offset: 0, length: 12
-// start_offset: 0, length: 117
-// For better cache management we collapse segments if they overlap or are
-// adjacent.
-
-namespace mswr = Microsoft::WRL;
-
-const char kFontKeyName[] = "font_key_name";
-
-// We use this value to determine whether to cache file fragments
-// or not. In our trials we observed that for some font files
-// direct write ends up reading almost entire file during enumeration
-// phase. If we don't use this percentile formula we will end up
-// increasing significant cache size by caching entire file contents
-// for some of the font files.
-const double kMaxPercentileOfFontFileSizeToCache = 0.6;
-
-// With current implementation we map entire shared section into memory during
-// renderer startup. This causes increase in working set of Chrome. As first
-// step we want to see if caching is really improving any performance for our
-// users, so we are putting arbitrary limit on cache file size. There are
-// multiple ways we can tune our working size, like mapping only required part
-// of section at any given time.
-const double kArbitraryCacheFileSizeLimit = (30 * 1024 * 1024);
-
-// We have chosen current font file length arbitrarily. In our logic
-// if we don't find file we are looking for in cache we end up loading
-// that file directly from system fonts folder.
-const unsigned int kMaxFontFileNameLength = 34;
-
-const DWORD kCacheFileVersion = 103;
-const DWORD kFileSignature = 0x4D4F5243; // CROM
-const DWORD kMagicCompletionSignature = 0x454E4F44; // DONE
-
-const DWORD kUndefinedDWORDS = 36;
-
-// Make sure that all structure sizes align with 8 byte boundary otherwise
-// dr. memory test may complain.
-#pragma pack(push, 8)
-// Cache file header, includes signature, completion bits and version.
-struct CacheFileHeader {
- CacheFileHeader() {
- file_signature = kFileSignature;
- magic_completion_signature = 0;
- version = kCacheFileVersion;
- ::ZeroMemory(undefined, sizeof(undefined));
- }
-
- DWORD file_signature;
- DWORD magic_completion_signature;
- DWORD version;
- BYTE undefined[kUndefinedDWORDS];
-};
-
-// Entry for a particular font file within this cache.
-struct CacheFileEntry {
- CacheFileEntry() {
- file_size = 0;
- entry_count = 0;
- ::ZeroMemory(file_name, sizeof(file_name));
- }
-
- UINT64 file_size;
- DWORD entry_count;
- wchar_t file_name[kMaxFontFileNameLength];
-};
-
-// Offsets or data chunks that are cached for particular font file.
-struct CacheFileOffsetEntry {
- CacheFileOffsetEntry() {
- start_offset = 0;
- length = 0;
- }
-
- UINT64 start_offset;
- UINT64 length;
- /* BYTE blob_[]; // Place holder for the blob that follows. */
-};
-#pragma pack(pop)
-
-bool ValidateFontCacheHeader(CacheFileHeader* header) {
- return (header->file_signature == kFileSignature &&
- header->magic_completion_signature == kMagicCompletionSignature &&
- header->version == kCacheFileVersion);
-}
-
-class FontCacheWriter;
-
-// This class implements main interface required for loading custom font
-// collection as specified by DirectWrite. We also use this class for storing
-// some state information as this is one of the centralized entity.
-class FontCollectionLoader
- : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
- IDWriteFontCollectionLoader> {
- public:
- FontCollectionLoader()
- : in_collection_building_mode_(false),
- create_static_cache_(false) {}
-
- ~FontCollectionLoader() override;
-
- HRESULT RuntimeClassInitialize() {
- return S_OK;
- }
-
- // IDWriteFontCollectionLoader methods.
- HRESULT STDMETHODCALLTYPE
- CreateEnumeratorFromKey(IDWriteFactory* factory,
- void const* key,
- UINT32 key_size,
- IDWriteFontFileEnumerator** file_enumerator) override;
-
- // Does all the initialization for required loading fonts from registry.
- static HRESULT Initialize(IDWriteFactory* factory);
-
- // Returns font cache map size.
- UINT32 GetFontMapSize();
-
- // Returns font name string when given font index.
- base::string16 GetFontNameFromKey(UINT32 idx);
-
- // Loads internal structure with fonts from registry.
- bool LoadFontListFromRegistry();
-
- // Loads restricted web safe fonts as fallback method to registry fonts.
- bool LoadRestrictedFontList();
-
- // Puts class in collection building mode. In collection building mode
- // we use static cache if it is available as a look aside buffer.
- void EnableCollectionBuildingMode(bool enable);
-
- // Returns current state of collection building.
- bool InCollectionBuildingMode();
-
- // Loads static cache file.
- bool LoadCacheFile();
-
- // Unloads cache file and related data.
- void UnloadCacheFile();
-
- // Puts class in static cache creating mode. In this mode we record all
- // direct write requests and store chunks of font data.
- void EnterStaticCacheMode(const WCHAR* file_name);
-
- // Gets out of static cache building mode.
- void LeaveStaticCacheMode();
-
- // Returns if class is currently in static cache building mode.
- bool IsBuildStaticCacheMode();
-
- // Validates cache file for consistency.
- bool ValidateCacheFile(base::File* file);
-
- private:
- // Structure to represent each chunk within font file that we load in memory.
- struct CacheTableOffsetEntry {
- UINT64 start_offset;
- UINT64 length;
- BYTE* inside_file_ptr;
- };
-
- typedef std::vector<CacheTableOffsetEntry> OffsetVector;
-
- // Structure representing each font entry with cache.
- struct CacheTableEntry {
- UINT64 file_size;
- OffsetVector offset_entries;
- };
-
- public:
- // Returns whether file we have particular font entry within cache or not.
- bool IsFileCached(UINT32 font_key);
- // Returns cache fragment corresponding to specific font key.
- void* GetCachedFragment(UINT32 font_key, UINT64 start_offset, UINT64 length);
- // Returns actual font file size at the time of caching.
- UINT64 GetCachedFileSize(UINT32 font_key);
-
- // Returns instance of font cache writer. This class manages actual font
- // file format.
- FontCacheWriter* GetFontCacheWriter();
-
- private:
- // Functions validates and loads cache into internal map.
- bool ValidateAndLoadCacheMap();
-
- mswr::ComPtr<IDWriteFontFileLoader> file_loader_;
-
- std::vector<base::string16> reg_fonts_;
- bool in_collection_building_mode_;
- bool create_static_cache_;
- scoped_ptr<base::SharedMemory> cache_;
- scoped_ptr<FontCacheWriter> cache_writer_;
-
- typedef std::map<base::string16, CacheTableEntry*> CacheMap;
- CacheMap cache_map_;
-
- DISALLOW_COPY_AND_ASSIGN(FontCollectionLoader);
-};
-
-mswr::ComPtr<FontCollectionLoader> g_font_loader;
-base::win::ScopedHandle g_shared_font_cache;
-
-// Class responsible for handling font cache file format details as well as
-// tracking various cache region requests by direct write.
-class FontCacheWriter {
- public:
- FontCacheWriter() : count_font_entries_ignored_(0), cookie_counter_(0) {}
-
- ~FontCacheWriter() {
- if (static_cache_.get()) {
- static_cache_->Close();
- }
- }
-
- public:
- // Holds data related to individual region as requested by direct write.
- struct CacheRegion {
- UINT64 start_offset;
- UINT64 length;
- const BYTE* ptr;
- /* BYTE blob_[]; // Place holder for the blob that follows. */
- };
-
- // Function to create static font cache file.
- bool Create(const wchar_t* file_name) {
- static_cache_.reset(new base::File(base::FilePath(file_name),
- base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
- base::File::FLAG_EXCLUSIVE_WRITE));
- if (!static_cache_->IsValid()) {
- static_cache_.reset();
- return false;
- }
- CacheFileHeader header;
-
- // At offset 0 write cache version
- static_cache_->Write(0,
- reinterpret_cast<const char*>(&header),
- sizeof(header));
-
- static_cache_->Flush();
- return true;
- }
-
- // Closes static font cache file. Also writes completion signature to mark
- // it as completely written.
- void Close() {
- if (static_cache_.get()) {
- CacheFileHeader header;
- header.magic_completion_signature = kMagicCompletionSignature;
- // At offset 0 write cache version
- int bytes_written = static_cache_->Write(0,
- reinterpret_cast<const char*>(&header),
- sizeof(header));
- DCHECK_NE(bytes_written, -1);
-
- UMA_HISTOGRAM_MEMORY_KB("DirectWrite.Fonts.BuildCache.File.Size",
- static_cache_->GetLength() / 1024);
-
- UMA_HISTOGRAM_COUNTS("DirectWrite.Fonts.BuildCache.Ignored",
- count_font_entries_ignored_);
-
- static_cache_->Close();
- static_cache_.reset(NULL);
- }
- }
-
- private:
- typedef std::vector<CacheRegion> RegionVector;
-
- // Structure to track various regions requested by direct write for particular
- // font file.
- struct FontEntryInternal {
- FontEntryInternal(const wchar_t* name, UINT64 size)
- : file_name(name),
- file_size(size) {
- }
-
- base::string16 file_name;
- UINT64 file_size;
- RegionVector regions;
- };
-
- public:
- // Starts up new font entry to be tracked, returns cookie to identify this
- // particular entry.
- UINT NewFontEntry(const wchar_t* file_name, UINT64 file_size) {
- base::AutoLock lock(lock_);
- UINT old_counter = cookie_counter_;
- FontEntryInternal* font_entry = new FontEntryInternal(file_name, file_size);
- cookie_map_[cookie_counter_].reset(font_entry);
- cookie_counter_++;
- return old_counter;
- }
-
- // AddRegion function lets caller add various regions to be cached for
- // particular font file. Once enumerating that particular font file is done
- // (based on uniquely identifying cookie) changes could be committed using
- // CommitFontEntry
- bool AddRegion(UINT64 cookie, UINT64 start, UINT64 length, const BYTE* ptr) {
- base::AutoLock lock(lock_);
- if (cookie_map_.find(cookie) == cookie_map_.end())
- return false;
- RegionVector& regions = cookie_map_[cookie].get()->regions;
- CacheRegion region;
- region.start_offset = start;
- region.length = length;
- region.ptr = ptr;
- regions.push_back(region);
- return true;
- }
-
- // Function which commits after merging all collected regions into cache file.
- bool CommitFontEntry(UINT cookie) {
- base::AutoLock lock(lock_);
- if (cookie_map_.find(cookie) == cookie_map_.end())
- return false;
-
- // We will skip writing entries beyond allowed limit. Following condition
- // doesn't enforce hard file size. We need to write complete font entry.
- int64_t length = static_cache_->GetLength();
- if (length == -1 || length >= kArbitraryCacheFileSizeLimit) {
- count_font_entries_ignored_++;
- return false;
- }
-
- FontEntryInternal* font_entry = cookie_map_[cookie].get();
- RegionVector& regions = font_entry->regions;
- std::sort(regions.begin(), regions.end(), SortCacheRegions);
-
- // At this point, we have collected all regions to be cached. These regions
- // are tuples of start, length, data for particular data segment.
- // These tuples can overlap.
- // e.g. (0, 12, data), (0, 117, data), (21, 314, data), (335, 15, data)
- // In this case as you can see first three segments overlap and
- // 4th is adjacent. If we cache them individually then we will end up
- // caching duplicate data, so we merge these segments together to find
- // superset for the cache. In above example our algorithm should
- // produce (cache) single segment starting at offset 0 with length 350.
- RegionVector merged_regions;
- RegionVector::iterator iter;
- int idx = 0;
- for (iter = regions.begin(); iter != regions.end(); iter++) {
- if (iter == regions.begin()) {
- merged_regions.push_back(*iter);
- continue;
- }
- CacheRegion& base_region = merged_regions[idx];
- if (IsOverlap(&base_region, &(*iter))) {
- UINT64 end1 = base_region.start_offset + base_region.length;
- UINT64 end2 = iter->start_offset + iter->length;
- if (base_region.start_offset > iter->start_offset) {
- base_region.start_offset = iter->start_offset;
- base_region.ptr = iter->ptr;
- }
- base_region.length = std::max(end1, end2) - base_region.start_offset;
- } else {
- merged_regions.push_back(*iter);
- idx++;
- }
- }
-
- UINT64 total_merged_cache_in_bytes = 0;
- for (iter = merged_regions.begin(); iter != merged_regions.end(); iter++) {
- total_merged_cache_in_bytes += iter->length;
- }
-
- // We want to adjust following parameter based on experiments. But general
- // logic here is that if we are going to end up caching most of the contents
- // for a file (e.g. simsunb.ttf > 90%) then we should avoid caching that
- // file.
- double percentile = static_cast<double>(total_merged_cache_in_bytes) /
- font_entry->file_size;
- if (percentile > kMaxPercentileOfFontFileSizeToCache) {
- count_font_entries_ignored_++;
- return false;
- }
-
- CacheFileEntry entry;
- wcsncpy_s(entry.file_name, kMaxFontFileNameLength,
- font_entry->file_name.c_str(), _TRUNCATE);
- entry.file_size = font_entry->file_size;
- entry.entry_count = merged_regions.size();
- static_cache_->WriteAtCurrentPos(
- reinterpret_cast<const char*>(&entry),
- sizeof(entry));
- for (iter = merged_regions.begin(); iter != merged_regions.end(); iter++) {
- CacheFileOffsetEntry offset_entry;
- offset_entry.start_offset = iter->start_offset;
- offset_entry.length = iter->length;
- static_cache_->WriteAtCurrentPos(
- reinterpret_cast<const char*>(&offset_entry),
- sizeof(offset_entry));
- static_cache_->WriteAtCurrentPos(
- reinterpret_cast<const char*>(iter->ptr),
- iter->length);
- }
- return true;
- }
-
- private:
- // This is the count of font entries that we reject based on size to be
- // cached.
- unsigned int count_font_entries_ignored_;
- scoped_ptr<base::File> static_cache_;
- std::map<UINT, scoped_ptr<FontEntryInternal>> cookie_map_;
- UINT cookie_counter_;
-
- // Lock is required to protect internal data structures and access to file,
- // According to MSDN documentation on ReadFileFragment and based on our
- // experiments so far, there is possibility of ReadFileFragment getting called
- // from multiple threads.
- base::Lock lock_;
-
- // Function checks if two regions overlap or are adjacent.
- bool IsOverlap(CacheRegion* region1, CacheRegion* region2) {
- return
- !((region1->start_offset + region1->length) < region2->start_offset ||
- region1->start_offset > (region2->start_offset + region2->length));
- }
-
- // Function to sort cached regions.
- static bool SortCacheRegions(const CacheRegion& region1,
- const CacheRegion& region2) {
- return
- region1.start_offset == region2.start_offset ?
- region1.length < region2.length :
- region1.start_offset < region2.start_offset;
- }
-
- DISALLOW_COPY_AND_ASSIGN(FontCacheWriter);
-};
-
-// Class implements IDWriteFontFileStream interface as required by direct write.
-class FontFileStream
- : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
- IDWriteFontFileStream> {
- public:
- // IDWriteFontFileStream methods.
- HRESULT STDMETHODCALLTYPE ReadFileFragment(
- void const** fragment_start,
- UINT64 file_offset,
- UINT64 fragment_size,
- void** context) override {
- if (cached_data_) {
- *fragment_start = g_font_loader->GetCachedFragment(font_key_,
- file_offset,
- fragment_size);
- if (*fragment_start == NULL) {
- DCHECK(false);
- }
- *context = NULL;
- return *fragment_start != NULL ? S_OK : E_FAIL;
- }
- if (!memory_.get() || !memory_->IsValid() ||
- file_offset >= memory_->length() ||
- (file_offset + fragment_size) > memory_->length())
- return E_FAIL;
-
- *fragment_start = static_cast<BYTE const*>(memory_->data()) +
- static_cast<size_t>(file_offset);
- *context = NULL;
- if (g_font_loader->IsBuildStaticCacheMode()) {
- FontCacheWriter* cache_writer = g_font_loader->GetFontCacheWriter();
- cache_writer->AddRegion(writer_cookie_,
- file_offset,
- fragment_size,
- static_cast<const BYTE*>(*fragment_start));
- }
- return S_OK;
- }
-
- void STDMETHODCALLTYPE ReleaseFileFragment(void* context) override {}
-
- HRESULT STDMETHODCALLTYPE GetFileSize(UINT64* file_size) override {
- if (cached_data_) {
- *file_size = g_font_loader->GetCachedFileSize(font_key_);
- return S_OK;
- }
-
- if (!memory_.get() || !memory_->IsValid())
- return E_FAIL;
-
- *file_size = memory_->length();
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE GetLastWriteTime(UINT64* last_write_time) override {
- if (cached_data_) {
- *last_write_time = 0;
- return S_OK;
- }
-
- if (!memory_.get() || !memory_->IsValid())
- return E_FAIL;
-
- // According to MSDN article http://goo.gl/rrSYzi the "last modified time"
- // is used by DirectWrite font selection algorithms to determine whether
- // one font resource is more up to date than another one.
- // So by returning 0 we are assuming that it will treat all fonts to be
- // equally up to date.
- // TODO(shrikant): We should further investigate this.
- *last_write_time = 0;
- return S_OK;
- }
-
- FontFileStream() : font_key_(0), cached_data_(false) {}
-
- HRESULT RuntimeClassInitialize(UINT32 font_key) {
- if (g_font_loader->InCollectionBuildingMode() &&
- g_font_loader->IsFileCached(font_key)) {
- cached_data_ = true;
- font_key_ = font_key;
- return S_OK;
- }
-
- base::FilePath path;
- PathService::Get(base::DIR_WINDOWS_FONTS, &path);
- base::string16 font_key_name(g_font_loader->GetFontNameFromKey(font_key));
- path = path.Append(font_key_name.c_str());
- memory_.reset(new base::MemoryMappedFile());
-
- // Put some debug information on stack.
- WCHAR font_name[MAX_PATH];
- path.value().copy(font_name, arraysize(font_name));
- base::debug::Alias(font_name);
-
- if (!memory_->Initialize(path)) {
- memory_.reset();
- return E_FAIL;
- }
-
- font_key_ = font_key;
-
- base::debug::SetCrashKeyValue(kFontKeyName,
- base::WideToUTF8(font_key_name));
-
- if (g_font_loader->IsBuildStaticCacheMode()) {
- FontCacheWriter* cache_writer = g_font_loader->GetFontCacheWriter();
- writer_cookie_ = cache_writer->NewFontEntry(font_key_name.c_str(),
- memory_->length());
- }
- return S_OK;
- }
-
- ~FontFileStream() override {
- if (g_font_loader->IsBuildStaticCacheMode()) {
- FontCacheWriter* cache_writer = g_font_loader->GetFontCacheWriter();
- cache_writer->CommitFontEntry(writer_cookie_);
- }
- }
-
- private:
- UINT32 font_key_;
- scoped_ptr<base::MemoryMappedFile> memory_;
- bool cached_data_;
- UINT writer_cookie_;
-
- DISALLOW_COPY_AND_ASSIGN(FontFileStream);
-};
-
-// Implements IDWriteFontFileLoader as required by FontFileLoader.
-class FontFileLoader
- : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
- IDWriteFontFileLoader> {
- public:
- // IDWriteFontFileLoader methods.
- HRESULT STDMETHODCALLTYPE
- CreateStreamFromKey(void const* ref_key,
- UINT32 ref_key_size,
- IDWriteFontFileStream** stream) override {
- if (ref_key_size != sizeof(UINT32))
- return E_FAIL;
-
- UINT32 font_key = *static_cast<const UINT32*>(ref_key);
- mswr::ComPtr<FontFileStream> font_stream;
- HRESULT hr = mswr::MakeAndInitialize<FontFileStream>(&font_stream,
- font_key);
- if (SUCCEEDED(hr)) {
- *stream = font_stream.Detach();
- return S_OK;
- }
- return E_FAIL;
- }
-
- FontFileLoader() {}
- ~FontFileLoader() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FontFileLoader);
-};
-
-// Implements IDWriteFontFileEnumerator as required by direct write.
-class FontFileEnumerator
- : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
- IDWriteFontFileEnumerator> {
- public:
- // IDWriteFontFileEnumerator methods.
- HRESULT STDMETHODCALLTYPE MoveNext(BOOL* has_current_file) override {
- *has_current_file = FALSE;
-
- if (current_file_)
- current_file_.ReleaseAndGetAddressOf();
-
- if (font_idx_ < g_font_loader->GetFontMapSize()) {
- HRESULT hr =
- factory_->CreateCustomFontFileReference(&font_idx_,
- sizeof(UINT32),
- file_loader_.Get(),
- current_file_.GetAddressOf());
- DCHECK(SUCCEEDED(hr));
- *has_current_file = TRUE;
- font_idx_++;
- }
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE
- GetCurrentFontFile(IDWriteFontFile** font_file) override {
- if (!current_file_) {
- *font_file = NULL;
- return E_FAIL;
- }
-
- *font_file = current_file_.Detach();
- return S_OK;
- }
-
- FontFileEnumerator(const void* keys,
- UINT32 buffer_size,
- IDWriteFactory* factory,
- IDWriteFontFileLoader* file_loader)
- : factory_(factory), file_loader_(file_loader), font_idx_(0) {}
-
- ~FontFileEnumerator() override {}
-
- mswr::ComPtr<IDWriteFactory> factory_;
- mswr::ComPtr<IDWriteFontFile> current_file_;
- mswr::ComPtr<IDWriteFontFileLoader> file_loader_;
- UINT32 font_idx_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FontFileEnumerator);
-};
-
-// IDWriteFontCollectionLoader methods.
-HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey(
- IDWriteFactory* factory,
- void const* key,
- UINT32 key_size,
- IDWriteFontFileEnumerator** file_enumerator) {
- *file_enumerator = mswr::Make<FontFileEnumerator>(
- key, key_size, factory, file_loader_.Get()).Detach();
- return S_OK;
-}
-
-// static
-HRESULT FontCollectionLoader::Initialize(IDWriteFactory* factory) {
- DCHECK(g_font_loader == NULL);
-
- HRESULT result;
- result = mswr::MakeAndInitialize<FontCollectionLoader>(&g_font_loader);
- if (FAILED(result) || !g_font_loader) {
- DCHECK(false);
- return E_FAIL;
- }
-
- CHECK(g_font_loader->LoadFontListFromRegistry());
-
- g_font_loader->file_loader_ = mswr::Make<FontFileLoader>().Detach();
-
- factory->RegisterFontFileLoader(g_font_loader->file_loader_.Get());
- factory->RegisterFontCollectionLoader(g_font_loader.Get());
-
- return S_OK;
-}
-
-FontCollectionLoader::~FontCollectionLoader() {
- STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end());
-}
-
-UINT32 FontCollectionLoader::GetFontMapSize() {
- return reg_fonts_.size();
-}
-
-base::string16 FontCollectionLoader::GetFontNameFromKey(UINT32 idx) {
- DCHECK(idx < reg_fonts_.size());
- return reg_fonts_[idx];
-}
-
-const base::FilePath::CharType* kFontExtensionsToIgnore[] {
- FILE_PATH_LITERAL(".FON"), // Bitmap or vector
- FILE_PATH_LITERAL(".PFM"), // Adobe Type 1
- FILE_PATH_LITERAL(".PFB"), // Adobe Type 1
-};
-
-const wchar_t* kFontsToIgnore[] = {
- // "Gill Sans Ultra Bold" turns into an Ultra Bold weight "Gill Sans" in
- // DirectWrite, but most users don't have any other weights. The regular
- // weight font is named "Gill Sans MT", but that ends up in a different
- // family with that name. On Mac, there's a "Gill Sans" with various weights,
- // so CSS authors use { 'font-family': 'Gill Sans', 'Gill Sans MT', ... } and
- // because of the DirectWrite family futzing, they end up with an Ultra Bold
- // font, when they just wanted "Gill Sans". Mozilla implemented a more
- // complicated hack where they effectively rename the Ultra Bold font to
- // "Gill Sans MT Ultra Bold", but because the Ultra Bold font is so ugly
- // anyway, we simply ignore it. See
- // http://www.microsoft.com/typography/fonts/font.aspx?FMID=978 for a picture
- // of the font, and the file name. We also ignore "Gill Sans Ultra Bold
- // Condensed".
- L"gilsanub.ttf",
- L"gillubcd.ttf",
-};
-
-bool FontCollectionLoader::LoadFontListFromRegistry() {
- const wchar_t kFontsRegistry[] =
- L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
- CHECK(reg_fonts_.empty());
- base::win::RegKey regkey;
- if (regkey.Open(HKEY_LOCAL_MACHINE, kFontsRegistry, KEY_READ) !=
- ERROR_SUCCESS) {
- return false;
- }
-
- base::FilePath system_font_path;
- PathService::Get(base::DIR_WINDOWS_FONTS, &system_font_path);
-
- base::string16 name;
- base::string16 value;
- for (DWORD idx = 0; idx < regkey.GetValueCount(); idx++) {
- if (regkey.GetValueNameAt(idx, &name) == ERROR_SUCCESS &&
- regkey.ReadValue(name.c_str(), &value) == ERROR_SUCCESS) {
- base::FilePath path(value.c_str());
- // We need to check if path in registry is absolute, if it is then
- // we check if it is same as DIR_WINDOWS_FONTS otherwise we ignore.
- bool absolute = path.IsAbsolute();
- if (absolute &&
- !base::FilePath::CompareEqualIgnoreCase(system_font_path.value(),
- path.DirName().value())) {
- continue;
- }
-
- // Ignore if path ends with a separator.
- if (path.EndsWithSeparator())
- continue;
-
- if (absolute)
- value = path.BaseName().value();
-
- bool should_ignore = false;
- for (const auto& ignore : kFontsToIgnore) {
- if (base::FilePath::CompareEqualIgnoreCase(value, ignore)) {
- should_ignore = true;
- break;
- }
- }
- // DirectWrite doesn't support bitmap/vector fonts and Adobe type 1
- // fonts, we will ignore those font extensions.
- // MSDN article: http://goo.gl/TfCOA
- if (!should_ignore) {
- for (const auto& ignore : kFontExtensionsToIgnore) {
- if (path.MatchesExtension(ignore)) {
- should_ignore = true;
- break;
- }
- }
- }
-
- if (!should_ignore)
- reg_fonts_.push_back(value.c_str());
- }
- }
- UMA_HISTOGRAM_COUNTS("DirectWrite.Fonts.Loaded", reg_fonts_.size());
- UMA_HISTOGRAM_COUNTS("DirectWrite.Fonts.Ignored",
- regkey.GetValueCount() - reg_fonts_.size());
- return true;
-}
-
-// This list is mainly based on prefs/prefs_tab_helper.cc kFontDefaults.
-const wchar_t* kRestrictedFontSet[] = {
- // These are the "Web Safe" fonts.
- L"times.ttf", // IDS_STANDARD_FONT_FAMILY
- L"timesbd.ttf", // IDS_STANDARD_FONT_FAMILY
- L"timesbi.ttf", // IDS_STANDARD_FONT_FAMILY
- L"timesi.ttf", // IDS_STANDARD_FONT_FAMILY
- L"cour.ttf", // IDS_FIXED_FONT_FAMILY
- L"courbd.ttf", // IDS_FIXED_FONT_FAMILY
- L"courbi.ttf", // IDS_FIXED_FONT_FAMILY
- L"couri.ttf", // IDS_FIXED_FONT_FAMILY
- L"consola.ttf", // IDS_FIXED_FONT_FAMILY_ALT_WIN
- L"consolab.ttf", // IDS_FIXED_FONT_FAMILY_ALT_WIN
- L"consolai.ttf", // IDS_FIXED_FONT_FAMILY_ALT_WIN
- L"consolaz.ttf", // IDS_FIXED_FONT_FAMILY_ALT_WIN
- L"arial.ttf", // IDS_SANS_SERIF_FONT_FAMILY
- L"arialbd.ttf", // IDS_SANS_SERIF_FONT_FAMILY
- L"arialbi.ttf", // IDS_SANS_SERIF_FONT_FAMILY
- L"ariali.ttf", // IDS_SANS_SERIF_FONT_FAMILY
- L"comic.ttf", // IDS_CURSIVE_FONT_FAMILY
- L"comicbd.ttf", // IDS_CURSIVE_FONT_FAMILY
- L"comici.ttf", // IDS_CURSIVE_FONT_FAMILY
- L"comicz.ttf", // IDS_CURSIVE_FONT_FAMILY
- L"impact.ttf", // IDS_FANTASY_FONT_FAMILY
- L"georgia.ttf",
- L"georgiab.ttf",
- L"georgiai.ttf",
- L"georgiaz.ttf",
- L"trebuc.ttf",
- L"trebucbd.ttf",
- L"trebucbi.ttf",
- L"trebucit.ttf",
- L"verdana.ttf",
- L"verdanab.ttf",
- L"verdanai.ttf",
- L"verdanaz.ttf",
- L"segoeui.ttf", // IDS_PICTOGRAPH_FONT_FAMILY
- L"segoeuib.ttf", // IDS_PICTOGRAPH_FONT_FAMILY
- L"segoeuii.ttf", // IDS_PICTOGRAPH_FONT_FAMILY
- L"msgothic.ttc", // IDS_STANDARD_FONT_FAMILY_JAPANESE
- L"msmincho.ttc", // IDS_SERIF_FONT_FAMILY_JAPANESE
- L"gulim.ttc", // IDS_FIXED_FONT_FAMILY_KOREAN
- L"batang.ttc", // IDS_SERIF_FONT_FAMILY_KOREAN
- L"simsun.ttc", // IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN
- L"mingliu.ttc", // IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN
-
- // These are from the Blink fallback list.
- L"david.ttf", // USCRIPT_HEBREW
- L"davidbd.ttf", // USCRIPT_HEBREW
- L"euphemia.ttf", // USCRIPT_CANADIAN_ABORIGINAL
- L"gautami.ttf", // USCRIPT_TELUGU
- L"gautamib.ttf", // USCRIPT_TELUGU
- L"latha.ttf", // USCRIPT_TAMIL
- L"lathab.ttf", // USCRIPT_TAMIL
- L"mangal.ttf", // USCRIPT_DEVANAGARI
- L"mangalb.ttf", // USCRIPT_DEVANAGARI
- L"monbaiti.ttf", // USCRIPT_MONGOLIAN
- L"mvboli.ttf", // USCRIPT_THAANA
- L"plantc.ttf", // USCRIPT_CHEROKEE
- L"raavi.ttf", // USCRIPT_GURMUKHI
- L"raavib.ttf", // USCRIPT_GURMUKHI
- L"shruti.ttf", // USCRIPT_GUJARATI
- L"shrutib.ttf", // USCRIPT_GUJARATI
- L"sylfaen.ttf", // USCRIPT_GEORGIAN and USCRIPT_ARMENIAN
- L"tahoma.ttf", // USCRIPT_ARABIC,
- L"tahomabd.ttf", // USCRIPT_ARABIC,
- L"tunga.ttf", // USCRIPT_KANNADA
- L"tungab.ttf", // USCRIPT_KANNADA
- L"vrinda.ttf", // USCRIPT_BENGALI
- L"vrindab.ttf", // USCRIPT_BENGALI
-};
-
-bool FontCollectionLoader::LoadRestrictedFontList() {
- reg_fonts_.clear();
- reg_fonts_.assign(kRestrictedFontSet,
- kRestrictedFontSet + _countof(kRestrictedFontSet));
- return true;
-}
-
-void FontCollectionLoader::EnableCollectionBuildingMode(bool enable) {
- in_collection_building_mode_ = enable;
-}
-
-bool FontCollectionLoader::InCollectionBuildingMode() {
- return in_collection_building_mode_;
-}
-
-bool FontCollectionLoader::IsFileCached(UINT32 font_key) {
- if (!cache_.get() || cache_->memory() == NULL) {
- return false;
- }
- CacheMap::iterator iter = cache_map_.find(
- GetFontNameFromKey(font_key).c_str());
- return iter != cache_map_.end();
-}
-
-bool FontCollectionLoader::LoadCacheFile() {
- TRACE_EVENT0("startup", "FontCollectionLoader::LoadCacheFile");
-
- std::string font_cache_handle_string =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kFontCacheSharedHandle);
- if (font_cache_handle_string.empty())
- return false;
-
- unsigned int handle_uint;
- base::StringToUint(font_cache_handle_string, &handle_uint);
- DCHECK(handle_uint);
- if (handle_uint > static_cast<unsigned int>(std::numeric_limits<long>::max()))
- return false;
- base::SharedMemoryHandle font_cache_handle(LongToHandle(handle_uint),
- base::GetCurrentProcId());
-
- base::SharedMemory* shared_mem = new base::SharedMemory(
- font_cache_handle, true);
- // Map the cache file into memory.
- shared_mem->Map(0);
-
- cache_.reset(shared_mem);
-
- if (base::StartsWith(base::FieldTrialList::FindFullName("LightSpeed"),
- "PrefetchDWriteFontCache",
- base::CompareCase::SENSITIVE)) {
- // Prefetch the cache, to avoid unordered IO when it is used.
- // PrefetchVirtualMemory() is loaded dynamically because it is only
- // available from Win8.
- decltype(PrefetchVirtualMemory)* prefetch_virtual_memory =
- reinterpret_cast<decltype(PrefetchVirtualMemory)*>(::GetProcAddress(
- ::GetModuleHandle(L"kernel32.dll"), "PrefetchVirtualMemory"));
- if (prefetch_virtual_memory != NULL) {
- WIN32_MEMORY_RANGE_ENTRY memory_range;
- memory_range.VirtualAddress = shared_mem->memory();
- memory_range.NumberOfBytes = shared_mem->mapped_size();
- prefetch_virtual_memory(::GetCurrentProcess(), 1, &memory_range, 0);
- }
- }
-
- if (!ValidateAndLoadCacheMap()) {
- cache_.reset();
- return false;
- }
-
- return true;
-}
-
-void FontCollectionLoader::UnloadCacheFile() {
- cache_.reset();
- STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end());
- cache_map_.clear();
-}
-
-void FontCollectionLoader::EnterStaticCacheMode(const WCHAR* file_name) {
- cache_writer_.reset(new FontCacheWriter());
- if (cache_writer_->Create(file_name))
- create_static_cache_ = true;
-}
-
-void FontCollectionLoader::LeaveStaticCacheMode() {
- cache_writer_->Close();
- cache_writer_.reset(NULL);
- create_static_cache_ = false;
-}
-
-bool FontCollectionLoader::IsBuildStaticCacheMode() {
- return create_static_cache_;
-}
-
-bool FontCollectionLoader::ValidateAndLoadCacheMap() {
- BYTE* mem_file_start = static_cast<BYTE*>(cache_->memory());
- BYTE* mem_file_end = mem_file_start + cache_->mapped_size();
-
- BYTE* current_ptr = mem_file_start;
- CacheFileHeader* file_header =
- reinterpret_cast<CacheFileHeader*>(current_ptr);
- if (!ValidateFontCacheHeader(file_header))
- return false;
-
- current_ptr = current_ptr + sizeof(CacheFileHeader);
- if (current_ptr >= mem_file_end)
- return false;
-
- while ((current_ptr + sizeof(CacheFileEntry)) < mem_file_end) {
- CacheFileEntry* entry = reinterpret_cast<CacheFileEntry*>(current_ptr);
- current_ptr += sizeof(CacheFileEntry);
- WCHAR file_name[kMaxFontFileNameLength];
- wcsncpy_s(file_name,
- kMaxFontFileNameLength,
- entry->file_name,
- _TRUNCATE);
- CacheTableEntry* table_entry = NULL;
- CacheMap::iterator iter = cache_map_.find(file_name);
- if (iter == cache_map_.end()) {
- table_entry = new CacheTableEntry();
- cache_map_[file_name] = table_entry;
- } else {
- table_entry = iter->second;
- }
- table_entry->file_size = entry->file_size;
- for (DWORD idx = 0;
- (current_ptr + sizeof(CacheFileOffsetEntry)) < mem_file_end &&
- idx < entry->entry_count;
- idx++) {
- CacheFileOffsetEntry* offset_entry =
- reinterpret_cast<CacheFileOffsetEntry*>(current_ptr);
- CacheTableOffsetEntry table_offset_entry;
- table_offset_entry.start_offset = offset_entry->start_offset;
- table_offset_entry.length = offset_entry->length;
- table_offset_entry.inside_file_ptr =
- current_ptr + sizeof(CacheFileOffsetEntry);
- table_entry->offset_entries.push_back(table_offset_entry);
- current_ptr += sizeof(CacheFileOffsetEntry);
- current_ptr += offset_entry->length;
- }
- }
-
- return true;
-}
-
-void* FontCollectionLoader::GetCachedFragment(UINT32 font_key,
- UINT64 start_offset,
- UINT64 length) {
- UINT64 just_past_end = start_offset + length;
- CacheMap::iterator iter = cache_map_.find(
- GetFontNameFromKey(font_key).c_str());
- if (iter != cache_map_.end()) {
- CacheTableEntry* entry = iter->second;
- OffsetVector::iterator offset_iter = entry->offset_entries.begin();
- while (offset_iter != entry->offset_entries.end()) {
- UINT64 available_just_past_end =
- offset_iter->start_offset + offset_iter->length;
- if (offset_iter->start_offset <= start_offset &&
- just_past_end <= available_just_past_end) {
- return offset_iter->inside_file_ptr +
- (start_offset - offset_iter->start_offset);
- }
- offset_iter++;
- }
- }
- return NULL;
-}
-
-UINT64 FontCollectionLoader::GetCachedFileSize(UINT32 font_key) {
- CacheMap::iterator iter = cache_map_.find(
- GetFontNameFromKey(font_key).c_str());
- if (iter != cache_map_.end()) {
- return iter->second->file_size;
- }
- return 0;
-}
-
-FontCacheWriter* FontCollectionLoader::GetFontCacheWriter() {
- return cache_writer_.get();
-}
-
-} // namespace
-
-namespace content {
-
-const char kFontCacheSharedSectionName[] = "ChromeDWriteFontCache";
-
-mswr::ComPtr<IDWriteFontCollection> g_font_collection;
-
-IDWriteFontCollection* GetCustomFontCollection(IDWriteFactory* factory) {
- if (g_font_collection.Get() != NULL)
- return g_font_collection.Get();
-
- TRACE_EVENT0("startup", "content::GetCustomFontCollection");
-
- base::TimeTicks start_tick = base::TimeTicks::Now();
-
- FontCollectionLoader::Initialize(factory);
-
- bool cache_file_loaded = g_font_loader->LoadCacheFile();
-
- // Arbitrary threshold to stop loading enormous number of fonts. Usual
- // side effect of loading large number of fonts results in renderer getting
- // killed as it appears to hang.
- const UINT32 kMaxFontThreshold = 1750;
- HRESULT hr = E_FAIL;
- if (cache_file_loaded ||
- g_font_loader->GetFontMapSize() < kMaxFontThreshold) {
- g_font_loader->EnableCollectionBuildingMode(true);
- hr = factory->CreateCustomFontCollection(
- g_font_loader.Get(), NULL, 0, g_font_collection.GetAddressOf());
- g_font_loader->UnloadCacheFile();
- g_font_loader->EnableCollectionBuildingMode(false);
- }
- bool loading_restricted = false;
- if (FAILED(hr) || !g_font_collection.Get()) {
- loading_restricted = true;
- // We will try here just one more time with restricted font set.
- g_font_loader->LoadRestrictedFontList();
- hr = factory->CreateCustomFontCollection(
- g_font_loader.Get(), NULL, 0, g_font_collection.GetAddressOf());
- }
-
- base::TimeDelta time_delta = base::TimeTicks::Now() - start_tick;
- int64_t delta = time_delta.ToInternalValue();
- base::debug::Alias(&delta);
- UINT32 size = g_font_loader->GetFontMapSize();
- base::debug::Alias(&size);
- base::debug::Alias(&loading_restricted);
-
- CHECK(SUCCEEDED(hr));
- CHECK(g_font_collection.Get() != NULL);
-
- if (cache_file_loaded)
- UMA_HISTOGRAM_TIMES("DirectWrite.Fonts.LoadTime.Cached", time_delta);
- else
- UMA_HISTOGRAM_TIMES("DirectWrite.Fonts.LoadTime", time_delta);
-
- base::debug::ClearCrashKey(kFontKeyName);
-
- return g_font_collection.Get();
-}
-
-bool BuildFontCacheInternal(const WCHAR* file_name) {
- typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc;
- HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll");
- if (!dwrite_dll) {
- DWORD load_library_get_last_error = GetLastError();
- base::debug::Alias(&dwrite_dll);
- base::debug::Alias(&load_library_get_last_error);
- CHECK(false);
- }
-
- DWriteCreateFactoryProc dwrite_create_factory_proc =
- reinterpret_cast<DWriteCreateFactoryProc>(
- GetProcAddress(dwrite_dll, "DWriteCreateFactory"));
-
- if (!dwrite_create_factory_proc) {
- DWORD get_proc_address_get_last_error = GetLastError();
- base::debug::Alias(&dwrite_create_factory_proc);
- base::debug::Alias(&get_proc_address_get_last_error);
- CHECK(false);
- }
-
- mswr::ComPtr<IDWriteFactory> factory;
-
- CHECK(SUCCEEDED(
- dwrite_create_factory_proc(
- DWRITE_FACTORY_TYPE_ISOLATED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(factory.GetAddressOf()))));
-
- base::TimeTicks start_tick = base::TimeTicks::Now();
-
- FontCollectionLoader::Initialize(factory.Get());
-
- g_font_loader->EnterStaticCacheMode(file_name);
-
- mswr::ComPtr<IDWriteFontCollection> font_collection;
-
- HRESULT hr = E_FAIL;
- g_font_loader->EnableCollectionBuildingMode(true);
- hr = factory->CreateCustomFontCollection(
- g_font_loader.Get(), NULL, 0, font_collection.GetAddressOf());
- g_font_loader->EnableCollectionBuildingMode(false);
-
- bool loading_restricted = false;
- if (FAILED(hr) || !font_collection.Get()) {
- loading_restricted = true;
- // We will try here just one more time with restricted font set.
- g_font_loader->LoadRestrictedFontList();
- hr = factory->CreateCustomFontCollection(
- g_font_loader.Get(), NULL, 0, font_collection.GetAddressOf());
- }
-
- g_font_loader->LeaveStaticCacheMode();
-
- base::TimeDelta time_delta = base::TimeTicks::Now() - start_tick;
- int64_t delta = time_delta.ToInternalValue();
- base::debug::Alias(&delta);
- UINT32 size = g_font_loader->GetFontMapSize();
- base::debug::Alias(&size);
- base::debug::Alias(&loading_restricted);
-
- CHECK(SUCCEEDED(hr));
- CHECK(font_collection.Get() != NULL);
-
- base::debug::ClearCrashKey(kFontKeyName);
-
- return true;
-}
-
-bool ValidateFontCacheFile(base::File* file) {
- DCHECK(file != NULL);
- CacheFileHeader file_header;
- if (file->Read(0, reinterpret_cast<char*>(&file_header), sizeof(file_header))
- == -1) {
- return false;
- }
- return ValidateFontCacheHeader(&file_header);
-}
-
-bool LoadFontCache(const base::FilePath& path) {
- scoped_ptr<base::File> file(new base::File(path,
- base::File::FLAG_OPEN | base::File::FLAG_READ));
- if (!file->IsValid())
- return false;
-
- if (!ValidateFontCacheFile(file.get()))
- return false;
-
- base::string16 name(base::ASCIIToUTF16(content::kFontCacheSharedSectionName));
- name.append(base::UintToString16(base::GetCurrentProcId()));
- HANDLE mapping = ::CreateFileMapping(
- file->GetPlatformFile(),
- NULL,
- PAGE_READONLY,
- 0,
- 0,
- name.c_str());
- if (mapping == INVALID_HANDLE_VALUE)
- return false;
-
- if (::GetLastError() == ERROR_ALREADY_EXISTS) {
- CloseHandle(mapping);
- // We crash here, as no one should have created this mapping except Chrome.
- CHECK(false);
- return false;
- }
-
- DCHECK(!g_shared_font_cache.IsValid());
- g_shared_font_cache.Set(mapping);
-
- return true;
-}
-
-bool BuildFontCache(const base::FilePath& file) {
- return BuildFontCacheInternal(file.value().c_str());
-}
-
-bool ShouldUseDirectWriteFontProxyFieldTrial() {
- return base::StartsWith(
- base::FieldTrialList::FindFullName("DirectWriteFontProxy"),
- "UseDirectWriteFontProxy", base::CompareCase::SENSITIVE);
-}
-
-} // namespace content
diff --git a/chromium/content/common/dwrite_font_platform_win_unittest.cc b/chromium/content/common/dwrite_font_platform_win_unittest.cc
deleted file mode 100644
index 4e517feedf6..00000000000
--- a/chromium/content/common/dwrite_font_platform_win_unittest.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 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 "content/public/common/dwrite_font_platform_win.h"
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "content/public/common/content_paths.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/win/direct_write.h"
-
-namespace content {
-
-class DWriteFontCacheTest : public testing::Test {
- public:
- DWriteFontCacheTest() { }
-
- void SetUp() override {
- base::FilePath data_path;
- ASSERT_TRUE(PathService::Get(content::DIR_TEST_DATA, &data_path));
- arial_cache_path_ =
- data_path.AppendASCII("font/dwrite_font_cache_arial.dat");
-
- corrupt_cache_path_ =
- data_path.AppendASCII("font/dwrite_font_cache_corrupt.dat");
-
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- cache_file_path_ = temp_dir_.path().AppendASCII("dwrite_font_cache.dat");
- }
-
- protected:
- base::FilePath arial_cache_path_;
- base::FilePath corrupt_cache_path_;
- base::ScopedTempDir temp_dir_;
- base::FilePath cache_file_path_;
-};
-
-TEST_F(DWriteFontCacheTest, BuildCacheTest) {
- if (gfx::win::ShouldUseDirectWrite()) {
- DLOG(INFO) << __FUNCTION__ << ": " << cache_file_path_.value().c_str();
- EXPECT_TRUE(BuildFontCache(cache_file_path_));
- ASSERT_TRUE(base::PathExists(cache_file_path_));
- }
-}
-
-TEST_F(DWriteFontCacheTest, ValidCacheTest) {
- if (gfx::win::ShouldUseDirectWrite()) {
- DLOG(INFO) << __FUNCTION__ << ": " << arial_cache_path_.value().c_str();
- scoped_ptr<base::File> file(new base::File(arial_cache_path_,
- base::File::FLAG_OPEN | base::File::FLAG_READ));
- ASSERT_TRUE(file->IsValid());
-
- EXPECT_TRUE(ValidateFontCacheFile(file.get()));
- }
-}
-
-TEST_F(DWriteFontCacheTest, CorruptCacheTest) {
- if (gfx::win::ShouldUseDirectWrite()) {
- DLOG(INFO) << __FUNCTION__ << ": " << corrupt_cache_path_.value().c_str();
- scoped_ptr<base::File> file(new base::File(corrupt_cache_path_,
- base::File::FLAG_OPEN | base::File::FLAG_READ));
- ASSERT_TRUE(file->IsValid());
-
- EXPECT_FALSE(ValidateFontCacheFile(file.get()));
- }
-}
-
-} // content
diff --git a/chromium/content/common/establish_channel_params.cc b/chromium/content/common/establish_channel_params.cc
new file mode 100644
index 00000000000..6ca5ac6a7bc
--- /dev/null
+++ b/chromium/content/common/establish_channel_params.cc
@@ -0,0 +1,18 @@
+// Copyright 2016 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 "content/common/establish_channel_params.h"
+
+namespace content {
+
+EstablishChannelParams::EstablishChannelParams()
+ : client_id(0),
+ client_tracing_id(0),
+ preempts(false),
+ allow_view_command_buffers(false),
+ allow_real_time_streams(false) {}
+
+EstablishChannelParams::~EstablishChannelParams() {}
+
+} // namespace content
diff --git a/chromium/content/common/establish_channel_params.h b/chromium/content/common/establish_channel_params.h
new file mode 100644
index 00000000000..f77b1bd8e48
--- /dev/null
+++ b/chromium/content/common/establish_channel_params.h
@@ -0,0 +1,27 @@
+// Copyright 2016 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 CONTENT_COMMON_ESTABLISH_CHANNEL_PARAMS_H_
+#define CONTENT_COMMON_ESTABLISH_CHANNEL_PARAMS_H_
+
+#include <stdint.h>
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+struct CONTENT_EXPORT EstablishChannelParams {
+ EstablishChannelParams();
+ ~EstablishChannelParams();
+
+ int client_id;
+ uint64_t client_tracing_id;
+ bool preempts;
+ bool allow_view_command_buffers;
+ bool allow_real_time_streams;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_ESTABLISH_CHANNEL_PARAMS_H_
diff --git a/chromium/content/common/experiments/api_key.cc b/chromium/content/common/experiments/api_key.cc
deleted file mode 100644
index 9199d5d776f..00000000000
--- a/chromium/content/common/experiments/api_key.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2015 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 "content/common/experiments/api_key.h"
-
-#include <openssl/curve25519.h>
-
-#include <vector>
-
-#include "base/base64.h"
-#include "base/macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "url/origin.h"
-
-namespace content {
-
-namespace {
-
-// This is the default public key used for validating signatures.
-// TODO(iclelland): Move this to the embedder, and provide a mechanism to allow
-// for multiple signing keys. https://crbug.com/543220
-static const uint8_t kPublicKey[] = {
- 0x7c, 0xc4, 0xb8, 0x9a, 0x93, 0xba, 0x6e, 0xe2, 0xd0, 0xfd, 0x03,
- 0x1d, 0xfb, 0x32, 0x66, 0xc7, 0x3b, 0x72, 0xfd, 0x54, 0x3a, 0x07,
- 0x51, 0x14, 0x66, 0xaa, 0x02, 0x53, 0x4e, 0x33, 0xa1, 0x15,
-};
-
-const char* kApiKeyFieldSeparator = "|";
-
-} // namespace
-
-ApiKey::~ApiKey() {}
-
-scoped_ptr<ApiKey> ApiKey::Parse(const std::string& key_text) {
- if (key_text.empty()) {
- return nullptr;
- }
-
- // API Key should resemble:
- // signature|origin|api_name|expiry_timestamp
- // TODO(iclelland): Add version code to API key format to identify key algo
- // https://crbug.com/570684
- std::vector<std::string> parts =
- SplitString(key_text, kApiKeyFieldSeparator, base::KEEP_WHITESPACE,
- base::SPLIT_WANT_ALL);
- if (parts.size() != 4) {
- return nullptr;
- }
-
- const std::string& signature = parts[0];
- const std::string& origin_string = parts[1];
- const std::string& api_name = parts[2];
- const std::string& expiry_string = parts[3];
-
- uint64_t expiry_timestamp;
- if (!base::StringToUint64(expiry_string, &expiry_timestamp)) {
- return nullptr;
- }
-
- // Ensure that the origin is a valid (non-unique) origin URL
- GURL origin_url(origin_string);
- if (url::Origin(origin_url).unique()) {
- return nullptr;
- }
-
- // signed data is (origin + "|" + api_name + "|" + expiry).
- std::string data = key_text.substr(signature.length() + 1);
-
- return make_scoped_ptr(
- new ApiKey(signature, data, origin_url, api_name, expiry_timestamp));
-}
-
-ApiKey::ApiKey(const std::string& signature,
- const std::string& data,
- const GURL& origin,
- const std::string& api_name,
- uint64_t expiry_timestamp)
- : signature_(signature),
- data_(data),
- origin_(origin),
- api_name_(api_name),
- expiry_timestamp_(expiry_timestamp) {}
-
-bool ApiKey::IsAppropriate(const std::string& origin,
- const std::string& api_name) const {
- return ValidateOrigin(origin) && ValidateApiName(api_name);
-}
-
-bool ApiKey::IsValid(const base::Time& now) const {
- // TODO(iclelland): Allow for multiple signing keys, and iterate over all
- // active keys here. https://crbug.com/543220
- return ValidateDate(now) &&
- ValidateSignature(base::StringPiece(
- reinterpret_cast<const char*>(kPublicKey), arraysize(kPublicKey)));
-}
-
-bool ApiKey::ValidateOrigin(const std::string& origin) const {
- return GURL(origin) == origin_;
-}
-
-bool ApiKey::ValidateApiName(const std::string& api_name) const {
- return base::EqualsCaseInsensitiveASCII(api_name, api_name_);
-}
-
-bool ApiKey::ValidateDate(const base::Time& now) const {
- base::Time expiry_time = base::Time::FromDoubleT((double)expiry_timestamp_);
- return expiry_time > now;
-}
-
-bool ApiKey::ValidateSignature(const base::StringPiece& public_key) const {
- return ValidateSignature(signature_, data_, public_key);
-}
-
-// static
-bool ApiKey::ValidateSignature(const std::string& signature_text,
- const std::string& data,
- const base::StringPiece& public_key) {
- // Public key must be 32 bytes long for Ed25519.
- CHECK_EQ(public_key.length(), 32UL);
-
- std::string signature;
- // signature_text is base64-encoded; decode first.
- if (!base::Base64Decode(signature_text, &signature)) {
- return false;
- }
-
- // Signature must be 64 bytes long
- if (signature.length() != 64) {
- return false;
- }
-
- int result = ED25519_verify(
- reinterpret_cast<const uint8_t*>(data.data()), data.length(),
- reinterpret_cast<const uint8_t*>(signature.data()),
- reinterpret_cast<const uint8_t*>(public_key.data()));
- return (result != 0);
-}
-
-} // namespace content
diff --git a/chromium/content/common/experiments/api_key.h b/chromium/content/common/experiments/api_key.h
deleted file mode 100644
index 1ad575a15e9..00000000000
--- a/chromium/content/common/experiments/api_key.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_EXPERIMENTS_API_KEY_H_
-#define CONTENT_COMMON_EXPERIMENTS_API_KEY_H_
-
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_piece.h"
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// The Experimental Framework (EF) provides limited access to experimental APIs,
-// on a per-origin basis. This class defines the API key data structure, used
-// to securely provide access to an experimental API.
-//
-// Experimental APIs are defined by string names, provided by the implementers.
-// The EF code does not maintain an enum or constant list for experiment names.
-// Instead, the EF validates the name provided by the API implementation against
-// any provided API keys.
-//
-// More documentation on the key format can be found at
-// https://docs.google.com/document/d/1v5fi0EUV_QHckVHVF2K4P72iNywnrJtNhNZ6i2NPt0M
-
-class CONTENT_EXPORT ApiKey {
- public:
- ~ApiKey();
-
- // Returns a key object if the string represents a well-formed key, or
- // nullptr otherwise. (This does not mean that the key is valid, just that it
- // can be parsed.)
- static scoped_ptr<ApiKey> Parse(const std::string& key_text);
-
- // Returns true if this API is appropriate for use by the given origin, for
- // the given API name. This does not check whether the signature is valid, or
- // whether the key itself has expired.
- bool IsAppropriate(const std::string& origin,
- const std::string& apiName) const;
-
- // Returns true if this API key has a valid signature, and has not expired.
- bool IsValid(const base::Time& now) const;
-
- std::string signature() { return signature_; }
- std::string data() { return data_; }
- GURL origin() { return origin_; }
- std::string api_name() { return api_name_; }
- uint64_t expiry_timestamp() { return expiry_timestamp_; }
-
- protected:
- friend class ApiKeyTest;
-
- bool ValidateOrigin(const std::string& origin) const;
- bool ValidateApiName(const std::string& api_name) const;
- bool ValidateDate(const base::Time& now) const;
- bool ValidateSignature(const base::StringPiece& public_key) const;
-
- static bool ValidateSignature(const std::string& signature_text,
- const std::string& data,
- const base::StringPiece& public_key);
-
- private:
- ApiKey(const std::string& signature,
- const std::string& data,
- const GURL& origin,
- const std::string& api_name,
- uint64_t expiry_timestamp);
-
- // The base64-encoded-signature portion of the key. For the key to be valid,
- // this must be a valid signature for the data portion of the key, as verified
- // by the public key in api_key.cc.
- std::string signature_;
-
- // The portion of the key string which is signed, and whose signature is
- // contained in the signature_ member.
- std::string data_;
-
- // The origin for which this key is valid. Must be a secure origin.
- GURL origin_;
-
- // The name of the API experiment which this key enables.
- std::string api_name_;
-
- // The time until which this key should be considered valid, in UTC, as
- // seconds since the Unix epoch.
- uint64_t expiry_timestamp_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_EXPERIMENTS_API_KEY_H_
diff --git a/chromium/content/common/experiments/api_key_unittest.cc b/chromium/content/common/experiments/api_key_unittest.cc
deleted file mode 100644
index a70ffcc92cf..00000000000
--- a/chromium/content/common/experiments/api_key_unittest.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2015 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 "content/common/experiments/api_key.h"
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_util.h"
-#include "base/test/simple_test_clock.h"
-#include "base/time/time.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-// This is a sample public key for testing the API. The corresponding private
-// key (use this to generate new samples for this test file) is:
-//
-// 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13,
-// 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba,
-// 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75,
-// 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a,
-// 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64,
-// 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0
-const uint8_t kTestPublicKey[] = {
- 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
- 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
- 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
-};
-
-// This is a good key, signed with the above test private key.
-const char* kSampleAPIKey =
- "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S"
- "dUwk7Dyk/qbDw==|https://valid.example.com|Frobulate|1458766277";
-const char* kExpectedAPIKeySignature =
- "UsEO0cNxoUtBnHDJdGPWTlXuLENjXcEIPL7Bs7sbvicPCcvAtyqhQuTJ9h/u1R3VZpWigtI+S"
- "dUwk7Dyk/qbDw==";
-const char* kExpectedAPIKeyData =
- "https://valid.example.com|Frobulate|1458766277";
-const char* kExpectedAPIName = "Frobulate";
-const char* kExpectedOrigin = "https://valid.example.com";
-const uint64_t kExpectedExpiry = 1458766277;
-
-// The key should not be valid for this origin, or for this API.
-const char* kInvalidOrigin = "https://invalid.example.com";
-const char* kInsecureOrigin = "http://valid.example.com";
-const char* kInvalidAPIName = "Grokalyze";
-
-// The key should be valid if the current time is kValidTimestamp or earlier.
-double kValidTimestamp = 1458766276.0;
-
-// The key should be invalid if the current time is kInvalidTimestamp or later.
-double kInvalidTimestamp = 1458766278.0;
-
-// Well-formed API key with an invalid signature.
-const char* kInvalidSignatureAPIKey =
- "CO8hDne98QeFeOJ0DbRZCBN3uE0nyaPgaLlkYhSWnbRoDfEAg+TXELaYfQPfEvKYFauBg/hnx"
- "mba765hz0mXMc==|https://valid.example.com|Frobulate|1458766277";
-
-// Various ill-formed API keys. These should all fail to parse.
-const char* kInvalidAPIKeys[] = {
- // Invalid - only one part
- "abcde",
- // Not enough parts
- "https://valid.example.com|APIName|1458766277",
- // Delimiter in API Name
- "Signature|https://valid.example.com|API|Name|1458766277",
- // Extra string field
- "Signature|https://valid.example.com|APIName|1458766277|SomethingElse",
- // Extra numeric field
- "Signature|https://valid.example.com|APIName|1458766277|1458766277",
- // Non-numeric expiry timestamp
- "Signature|https://valid.example.com|APIName|abcdefghij",
- "Signature|https://valid.example.com|APIName|1458766277x",
- // Negative expiry timestamp
- "Signature|https://valid.example.com|APIName|-1458766277",
- // Origin not a proper origin URL
- "Signature|abcdef|APIName|1458766277",
- "Signature|data:text/plain,abcdef|APIName|1458766277",
- "Signature|javascript:alert(1)|APIName|1458766277"};
-const size_t kNumInvalidAPIKeys = arraysize(kInvalidAPIKeys);
-
-} // namespace
-
-class ApiKeyTest : public testing::Test {
- public:
- ApiKeyTest()
- : public_key_(
- base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
- arraysize(kTestPublicKey))) {}
-
- protected:
- bool ValidateOrigin(ApiKey* api_key, const char* origin) {
- return api_key->ValidateOrigin(origin);
- }
-
- bool ValidateApiName(ApiKey* api_key, const char* api_name) {
- return api_key->ValidateApiName(api_name);
- }
-
- bool ValidateDate(ApiKey* api_key, const base::Time& now) {
- return api_key->ValidateDate(now);
- }
-
- bool ValidateSignature(ApiKey* api_key, const base::StringPiece& public_key) {
- return api_key->ValidateSignature(public_key);
- }
-
- const base::StringPiece& public_key() { return public_key_; };
-
- private:
- base::StringPiece public_key_;
-};
-
-TEST_F(ApiKeyTest, ParseEmptyString) {
- scoped_ptr<ApiKey> empty_key = ApiKey::Parse("");
- EXPECT_FALSE(empty_key);
-}
-
-TEST_F(ApiKeyTest, ParseInvalidStrings) {
- for (size_t i = 0; i < kNumInvalidAPIKeys; ++i) {
- scoped_ptr<ApiKey> empty_key = ApiKey::Parse(kInvalidAPIKeys[i]);
- EXPECT_FALSE(empty_key) << "Invalid API Key should not parse: "
- << kInvalidAPIKeys[i];
- }
-}
-
-TEST_F(ApiKeyTest, ParseValidKeyString) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
- EXPECT_EQ(kExpectedAPIName, key->api_name());
- EXPECT_EQ(kExpectedAPIKeySignature, key->signature());
- EXPECT_EQ(kExpectedAPIKeyData, key->data());
- EXPECT_EQ(GURL(kExpectedOrigin), key->origin());
- EXPECT_EQ(kExpectedExpiry, key->expiry_timestamp());
-}
-
-TEST_F(ApiKeyTest, ValidateValidKey) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
- EXPECT_TRUE(ValidateOrigin(key.get(), kExpectedOrigin));
- EXPECT_FALSE(ValidateOrigin(key.get(), kInvalidOrigin));
- EXPECT_FALSE(ValidateOrigin(key.get(), kInsecureOrigin));
- EXPECT_TRUE(ValidateApiName(key.get(), kExpectedAPIName));
- EXPECT_FALSE(ValidateApiName(key.get(), kInvalidAPIName));
- EXPECT_TRUE(
- ValidateDate(key.get(), base::Time::FromDoubleT(kValidTimestamp)));
- EXPECT_FALSE(
- ValidateDate(key.get(), base::Time::FromDoubleT(kInvalidTimestamp)));
-}
-
-TEST_F(ApiKeyTest, KeyIsAppropriateForOriginAndAPI) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
- EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin, kExpectedAPIName));
- EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin,
- base::ToUpperASCII(kExpectedAPIName)));
- EXPECT_TRUE(key->IsAppropriate(kExpectedOrigin,
- base::ToLowerASCII(kExpectedAPIName)));
- EXPECT_FALSE(key->IsAppropriate(kInvalidOrigin, kExpectedAPIName));
- EXPECT_FALSE(key->IsAppropriate(kInsecureOrigin, kExpectedAPIName));
- EXPECT_FALSE(key->IsAppropriate(kExpectedOrigin, kInvalidAPIName));
-}
-
-TEST_F(ApiKeyTest, ValidateValidSignature) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
- EXPECT_TRUE(ValidateSignature(key.get(), public_key()));
-}
-
-TEST_F(ApiKeyTest, ValidateInvalidSignature) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kInvalidSignatureAPIKey);
- ASSERT_TRUE(key);
- EXPECT_FALSE(ValidateSignature(key.get(), public_key()));
-}
-
-TEST_F(ApiKeyTest, ValidateSignatureOnWrongKey) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
- // Signature will be invalid if tested against the real public key
- EXPECT_FALSE(key->IsValid(base::Time::FromDoubleT(kValidTimestamp)));
-}
-
-TEST_F(ApiKeyTest, ValidateWhenNotExpired) {
- scoped_ptr<ApiKey> key = ApiKey::Parse(kSampleAPIKey);
- ASSERT_TRUE(key);
-}
-
-} // namespace content
diff --git a/chromium/content/common/fileapi/webblob_messages.h b/chromium/content/common/fileapi/webblob_messages.h
index a836fd4f5ae..85dbf8c976c 100644
--- a/chromium/content/common/fileapi/webblob_messages.h
+++ b/chromium/content/common/fileapi/webblob_messages.h
@@ -7,29 +7,81 @@
#include <stddef.h>
+#include <set>
+
+#include "base/memory/shared_memory.h"
#include "content/common/content_export.h"
-#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_param_traits.h"
+#include "ipc/ipc_platform_file.h"
+#include "storage/common/blob_storage/blob_item_bytes_request.h"
+#include "storage/common/blob_storage/blob_item_bytes_response.h"
+#include "storage/common/blob_storage/blob_storage_constants.h"
#include "storage/common/data_element.h"
+#include "url/ipc/url_param_traits.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START BlobMsgStart
-// Blob messages sent from the renderer to the browser.
-
-IPC_MESSAGE_CONTROL1(BlobHostMsg_StartBuilding,
- std::string /*uuid */)
-IPC_MESSAGE_CONTROL2(BlobHostMsg_AppendBlobDataItem,
+// Trait definitions for async blob transport messages.
+
+IPC_ENUM_TRAITS_MAX_VALUE(storage::IPCBlobItemRequestStrategy,
+ storage::IPCBlobItemRequestStrategy::LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(storage::IPCBlobCreationCancelCode,
+ storage::IPCBlobCreationCancelCode::LAST)
+
+IPC_STRUCT_TRAITS_BEGIN(storage::BlobItemBytesRequest)
+ IPC_STRUCT_TRAITS_MEMBER(request_number)
+ IPC_STRUCT_TRAITS_MEMBER(transport_strategy)
+ IPC_STRUCT_TRAITS_MEMBER(renderer_item_index)
+ IPC_STRUCT_TRAITS_MEMBER(renderer_item_offset)
+ IPC_STRUCT_TRAITS_MEMBER(size)
+ IPC_STRUCT_TRAITS_MEMBER(handle_index)
+ IPC_STRUCT_TRAITS_MEMBER(handle_offset)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(storage::BlobItemBytesResponse)
+ IPC_STRUCT_TRAITS_MEMBER(request_number)
+ IPC_STRUCT_TRAITS_MEMBER(inline_data)
+ IPC_STRUCT_TRAITS_MEMBER(time_file_modified)
+IPC_STRUCT_TRAITS_END()
+
+// This message is to tell the browser that we will be building a blob.
+IPC_MESSAGE_CONTROL4(BlobStorageMsg_RegisterBlobUUID,
std::string /* uuid */,
- storage::DataElement)
-IPC_SYNC_MESSAGE_CONTROL3_0(BlobHostMsg_SyncAppendSharedMemory,
- std::string /*uuid*/,
- base::SharedMemoryHandle,
- size_t /* buffer size */)
-IPC_MESSAGE_CONTROL2(BlobHostMsg_FinishBuilding,
+ std::string /* content_type */,
+ std::string /* content_disposition */,
+ std::set<std::string> /* referenced_blob_uuids */)
+
+// The DataElements are used to:
+// * describe & transport non-memory resources (blobs, files, etc)
+// * describe the size of memory items
+// * 'shortcut' transport the memory up to the IPC limit so the browser can use
+// it if it's not currently full.
+// See https://bit.ly/BlobStorageRefactor
+IPC_MESSAGE_CONTROL2(BlobStorageMsg_StartBuildingBlob,
std::string /* uuid */,
- std::string /* content_type */)
+ std::vector<storage::DataElement> /* item_descriptions */)
+
+IPC_MESSAGE_CONTROL4(
+ BlobStorageMsg_RequestMemoryItem,
+ std::string /* uuid */,
+ std::vector<storage::BlobItemBytesRequest> /* requests */,
+ std::vector<base::SharedMemoryHandle> /* memory_handles */,
+ std::vector<IPC::PlatformFileForTransit> /* file_handles */)
+
+IPC_MESSAGE_CONTROL2(
+ BlobStorageMsg_MemoryItemResponse,
+ std::string /* uuid */,
+ std::vector<storage::BlobItemBytesResponse> /* responses */)
+
+IPC_MESSAGE_CONTROL2(BlobStorageMsg_CancelBuildingBlob,
+ std::string /* uuid */,
+ storage::IPCBlobCreationCancelCode /* code */)
+
+IPC_MESSAGE_CONTROL1(BlobStorageMsg_DoneBuildingBlob, std::string /* uuid */)
IPC_MESSAGE_CONTROL1(BlobHostMsg_IncrementRefCount,
std::string /* uuid */)
@@ -57,7 +109,7 @@ IPC_MESSAGE_CONTROL2(StreamHostMsg_AppendBlobDataItem,
IPC_SYNC_MESSAGE_CONTROL3_0(StreamHostMsg_SyncAppendSharedMemory,
GURL /* url */,
base::SharedMemoryHandle,
- size_t /* buffer size */)
+ uint32_t /* buffer size */)
// Flushes contents buffered in the stream.
IPC_MESSAGE_CONTROL1(StreamHostMsg_Flush,
diff --git a/chromium/content/common/font_config_ipc_linux.cc b/chromium/content/common/font_config_ipc_linux.cc
index d1dd8ca187f..294bcf83fbf 100644
--- a/chromium/content/common/font_config_ipc_linux.cc
+++ b/chromium/content/common/font_config_ipc_linux.cc
@@ -13,9 +13,12 @@
#include <sys/uio.h>
#include <unistd.h>
+#include <functional>
+
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
#include "base/posix/unix_domain_socket_linux.h"
#include "base/threading/thread_restrictions.h"
@@ -26,13 +29,12 @@
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
+namespace content {
-namespace BASE_HASH_NAMESPACE {
-
-std::size_t hash<SkFontConfigInterface::FontIdentity>::operator()(
+std::size_t SkFontConfigInterfaceFontIdentityHash::operator()(
const SkFontConfigInterface::FontIdentity& sp) const {
- hash<std::string> stringhash;
- hash<int> inthash;
+ std::hash<std::string> stringhash;
+ std::hash<int> inthash;
size_t r = inthash(sp.fID);
r = r * 41 + inthash(sp.fTTCIndex);
r = r * 41 + stringhash(sp.fString.c_str());
@@ -42,10 +44,6 @@ std::size_t hash<SkFontConfigInterface::FontIdentity>::operator()(
return r;
}
-} // namespace BASE_HASH_NAMESPACE
-
-namespace content {
-
// Wikpedia's main country selection page activates 21 fallback fonts,
// doubling this we should be on the generous side as an upper bound,
// but nevertheless not have the mapped typefaces cache grow excessively.
diff --git a/chromium/content/common/font_config_ipc_linux.h b/chromium/content/common/font_config_ipc_linux.h
index 472c2f1aab4..5e969cd2f12 100644
--- a/chromium/content/common/font_config_ipc_linux.h
+++ b/chromium/content/common/font_config_ipc_linux.h
@@ -20,18 +20,14 @@
class SkString;
-namespace BASE_HASH_NAMESPACE {
-template <>
-struct hash<SkFontConfigInterface::FontIdentity> {
- std::size_t operator()(const SkFontConfigInterface::FontIdentity& sp) const;
-};
-}
-
namespace content {
+struct SkFontConfigInterfaceFontIdentityHash {
+ std::size_t operator()(const SkFontConfigInterface::FontIdentity& sp) const;
+};
// FontConfig implementation for Skia that proxies out of process to get out
-// of the sandbox. See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
+// of the sandbox. See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md
class FontConfigIPC : public SkFontConfigInterface {
public:
explicit FontConfigIPC(int fd);
@@ -74,7 +70,9 @@ class FontConfigIPC : public SkFontConfigInterface {
// ttc-indices or styles but the same fontconfig interface id. Since the usage
// frequency of ttc indices is very low, and style is not used by clients of
// this API, this seems okay.
- base::HashingMRUCache<FontIdentity, skia::RefPtr<SkTypeface>>
+ base::HashingMRUCache<FontIdentity,
+ skia::RefPtr<SkTypeface>,
+ SkFontConfigInterfaceFontIdentityHash>
mapped_typefaces_;
DISALLOW_COPY_AND_ASSIGN(FontConfigIPC);
diff --git a/chromium/content/common/font_list_win.cc b/chromium/content/common/font_list_win.cc
index 2e07efa0689..62717ec3d24 100644
--- a/chromium/content/common/font_list_win.cc
+++ b/chromium/content/common/font_list_win.cc
@@ -50,7 +50,7 @@ scoped_ptr<base::ListValue> GetFontList_SlowBlocking() {
font_item->Append(new base::StringValue(*iter));
font_list->Append(font_item);
}
- return font_list.Pass();
+ return font_list;
}
} // namespace content
diff --git a/chromium/content/common/font_warmup_win.cc b/chromium/content/common/font_warmup_win.cc
deleted file mode 100644
index cdd1d0f2dba..00000000000
--- a/chromium/content/common/font_warmup_win.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2014 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 "content/common/font_warmup_win.h"
-
-#include <dwrite.h>
-#include <stdint.h>
-#include <map>
-
-#include "base/debug/alias.h"
-#include "base/files/file_path.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/numerics/safe_math.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/synchronization/lock.h"
-#include "base/sys_byteorder.h"
-#include "base/trace_event/trace_event.h"
-#include "base/win/iat_patch_function.h"
-#include "base/win/windows_version.h"
-#include "content/public/common/dwrite_font_platform_win.h"
-#include "ppapi/shared_impl/proxy_lock.h"
-#include "skia/ext/fontmgr_default_win.h"
-#include "skia/ext/refptr.h"
-#include "third_party/WebKit/public/web/win/WebFontRendering.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
-#include "third_party/skia/include/ports/SkTypeface_win.h"
-
-namespace content {
-
-namespace {
-
-// The Skia font manager, used for the life of the process (leaked at the end).
-SkFontMgr* g_warmup_fontmgr = nullptr;
-
-base::win::IATPatchFunction g_iat_patch_open_sc_manager;
-base::win::IATPatchFunction g_iat_patch_close_service_handle;
-base::win::IATPatchFunction g_iat_patch_open_service;
-base::win::IATPatchFunction g_iat_patch_start_service;
-base::win::IATPatchFunction g_iat_patch_nt_connect_port;
-
-// These are from ntddk.h
-#if !defined(STATUS_ACCESS_DENIED)
-#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
-#endif
-
-typedef LONG NTSTATUS;
-
-const uintptr_t kFakeSCMHandle = 0xdead0001;
-const uintptr_t kFakeServiceHandle = 0xdead0002;
-
-SC_HANDLE WINAPI OpenSCManagerWPatch(const wchar_t* machine_name,
- const wchar_t* database_name,
- DWORD access_mask) {
- ::SetLastError(0);
- return reinterpret_cast<SC_HANDLE>(kFakeSCMHandle);
-}
-
-SC_HANDLE WINAPI OpenServiceWPatch(SC_HANDLE sc_manager,
- const wchar_t* service_name,
- DWORD access_mask) {
- ::SetLastError(0);
- return reinterpret_cast<SC_HANDLE>(kFakeServiceHandle);
-}
-
-BOOL WINAPI CloseServiceHandlePatch(SC_HANDLE service_handle) {
- if (service_handle != reinterpret_cast<SC_HANDLE>(kFakeServiceHandle) &&
- service_handle != reinterpret_cast<SC_HANDLE>(kFakeSCMHandle))
- CHECK(false);
- ::SetLastError(0);
- return TRUE;
-}
-
-BOOL WINAPI StartServiceWPatch(SC_HANDLE service,
- DWORD args,
- const wchar_t** arg_vectors) {
- if (service != reinterpret_cast<SC_HANDLE>(kFakeServiceHandle))
- CHECK(false);
- ::SetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
-}
-
-NTSTATUS WINAPI NtALpcConnectPortPatch(HANDLE* port_handle,
- void* port_name,
- void* object_attribs,
- void* port_attribs,
- DWORD flags,
- void* server_sid,
- void* message,
- DWORD* buffer_length,
- void* out_message_attributes,
- void* in_message_attributes,
- void* time_out) {
- return STATUS_ACCESS_DENIED;
-}
-
-// Windows-only DirectWrite support. These warm up the DirectWrite paths
-// before sandbox lock down to allow Skia access to the Font Manager service.
-void CreateDirectWriteFactory(IDWriteFactory** factory) {
- typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc;
- HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll");
- // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867.
- if (!dwrite_dll) {
- DWORD load_library_get_last_error = GetLastError();
- base::debug::Alias(&dwrite_dll);
- base::debug::Alias(&load_library_get_last_error);
- CHECK(false);
- }
-
- PatchServiceManagerCalls();
-
- DWriteCreateFactoryProc dwrite_create_factory_proc =
- reinterpret_cast<DWriteCreateFactoryProc>(
- GetProcAddress(dwrite_dll, "DWriteCreateFactory"));
- // TODO(scottmg): Temporary code to track crash in http://crbug.com/387867.
- if (!dwrite_create_factory_proc) {
- DWORD get_proc_address_get_last_error = GetLastError();
- base::debug::Alias(&dwrite_create_factory_proc);
- base::debug::Alias(&get_proc_address_get_last_error);
- CHECK(false);
- }
- CHECK(SUCCEEDED(dwrite_create_factory_proc(
- DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(factory))));
-}
-
-HRESULT STDMETHODCALLTYPE StubFontCollection(IDWriteFactory* factory,
- IDWriteFontCollection** col,
- BOOL checkUpdates) {
- // We always return pre-created font collection from here.
- IDWriteFontCollection* custom_collection = GetCustomFontCollection(factory);
- DCHECK(custom_collection != nullptr);
- *col = custom_collection;
- return S_OK;
-}
-
-void PatchDWriteFactory(IDWriteFactory* factory) {
- const unsigned int kGetSystemFontCollectionVTableIndex = 3;
-
- PROC* vtable = *reinterpret_cast<PROC**>(factory);
- PROC* function_ptr = &vtable[kGetSystemFontCollectionVTableIndex];
- void* stub_function = &StubFontCollection;
- base::win::ModifyCode(function_ptr, &stub_function, sizeof(PROC));
-}
-
-// Class to fake out a DC or a Font object. Maintains a reference to a
-// SkTypeFace to emulate the simple operation of a DC and Font.
-class FakeGdiObject : public base::RefCountedThreadSafe<FakeGdiObject> {
- public:
- FakeGdiObject(uint32_t magic, void* handle)
- : handle_(handle), magic_(magic) {}
-
- void set_typeface(const skia::RefPtr<SkTypeface>& typeface) {
- typeface_ = typeface;
- }
-
- skia::RefPtr<SkTypeface> typeface() { return typeface_; }
- void* handle() { return handle_; }
- uint32_t magic() { return magic_; }
-
- private:
- friend class base::RefCountedThreadSafe<FakeGdiObject>;
- ~FakeGdiObject() {}
-
- void* handle_;
- uint32_t magic_;
- skia::RefPtr<SkTypeface> typeface_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeGdiObject);
-};
-
-// This class acts as a factory for creating new fake GDI objects. It also maps
-// the new instances of the FakeGdiObject class to an incrementing handle value
-// which is passed to the caller of the emulated GDI function for later
-// reference. We can't be sure that this won't be used in a multi-threaded
-// environment so we need to ensure a lock is taken before accessing the map of
-// issued objects.
-class FakeGdiObjectFactory {
- public:
- FakeGdiObjectFactory() : curr_handle_(0) {}
-
- // Find a corresponding fake GDI object and verify its magic value.
- // The returned value is either nullptr or the validated object.
- scoped_refptr<FakeGdiObject> Validate(void* obj, uint32_t magic) {
- if (obj) {
- base::AutoLock scoped_lock(objects_lock_);
- auto handle_entry = objects_.find(obj);
- if (handle_entry != objects_.end() &&
- handle_entry->second->magic() == magic) {
- return handle_entry->second;
- }
- }
- return nullptr;
- }
-
- scoped_refptr<FakeGdiObject> Create(uint32_t magic) {
- base::AutoLock scoped_lock(objects_lock_);
- curr_handle_++;
- // We don't support wrapping the fake handle value.
- void* handle = reinterpret_cast<void*>(curr_handle_.ValueOrDie());
- scoped_refptr<FakeGdiObject> object(new FakeGdiObject(magic, handle));
- objects_[handle] = object;
- return object;
- }
-
- bool DeleteObject(void* obj, uint32_t magic) {
- base::AutoLock scoped_lock(objects_lock_);
- auto handle_entry = objects_.find(obj);
- if (handle_entry != objects_.end() &&
- handle_entry->second->magic() == magic) {
- objects_.erase(handle_entry);
- return true;
- }
- return false;
- }
-
- size_t GetObjectCount() {
- base::AutoLock scoped_lock(objects_lock_);
- return objects_.size();
- }
-
- void ResetObjectHandles() {
- base::AutoLock scoped_lock(objects_lock_);
- curr_handle_ = 0;
- objects_.clear();
- }
-
- private:
- base::CheckedNumeric<uintptr_t> curr_handle_;
- std::map<void*, scoped_refptr<FakeGdiObject>> objects_;
- base::Lock objects_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeGdiObjectFactory);
-};
-
-base::LazyInstance<FakeGdiObjectFactory>::Leaky g_fake_gdi_object_factory =
- LAZY_INSTANCE_INITIALIZER;
-
-// Magic values for the fake GDI objects.
-const uint32_t kFakeDCMagic = 'fkdc';
-const uint32_t kFakeFontMagic = 'fkft';
-
-skia::RefPtr<SkTypeface> GetTypefaceFromLOGFONT(const LOGFONTW* log_font) {
- CHECK(g_warmup_fontmgr);
- int weight = log_font->lfWeight;
- if (weight == FW_DONTCARE)
- weight = SkFontStyle::kNormal_Weight;
-
- SkFontStyle style(weight, log_font->lfWidth,
- log_font->lfItalic ? SkFontStyle::kItalic_Slant
- : SkFontStyle::kUpright_Slant);
-
- std::string family_name = base::WideToUTF8(log_font->lfFaceName);
- ppapi::ProxyAutoLock lock; // Needed for DirectWrite font proxy.
- return skia::AdoptRef(
- g_warmup_fontmgr->matchFamilyStyle(family_name.c_str(), style));
-}
-
-HDC WINAPI CreateCompatibleDCPatch(HDC dc_handle) {
- scoped_refptr<FakeGdiObject> ret =
- g_fake_gdi_object_factory.Get().Create(kFakeDCMagic);
- return static_cast<HDC>(ret->handle());
-}
-
-HFONT WINAPI CreateFontIndirectWPatch(const LOGFONTW* log_font) {
- if (!log_font)
- return nullptr;
-
- skia::RefPtr<SkTypeface> typeface = GetTypefaceFromLOGFONT(log_font);
- if (!typeface)
- return nullptr;
-
- scoped_refptr<FakeGdiObject> ret =
- g_fake_gdi_object_factory.Get().Create(kFakeFontMagic);
- ret->set_typeface(typeface);
-
- return static_cast<HFONT>(ret->handle());
-}
-
-BOOL WINAPI DeleteDCPatch(HDC dc_handle) {
- return g_fake_gdi_object_factory.Get().DeleteObject(dc_handle, kFakeDCMagic);
-}
-
-BOOL WINAPI DeleteObjectPatch(HGDIOBJ object_handle) {
- return g_fake_gdi_object_factory.Get().DeleteObject(object_handle,
- kFakeFontMagic);
-}
-
-int WINAPI EnumFontFamiliesExWPatch(HDC dc_handle,
- LPLOGFONTW log_font,
- FONTENUMPROCW enum_callback,
- LPARAM callback_param,
- DWORD flags) {
- scoped_refptr<FakeGdiObject> dc_obj =
- g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
- if (!dc_obj)
- return 1;
-
- if (!log_font || !enum_callback)
- return 1;
-
- skia::RefPtr<SkTypeface> typeface = GetTypefaceFromLOGFONT(log_font);
- if (!typeface)
- return 1;
-
- ENUMLOGFONTEXDVW enum_log_font = {};
- enum_log_font.elfEnumLogfontEx.elfLogFont = *log_font;
- // TODO: Fill in the rest of the text metric structure. Not yet needed for
- // Flash support but might be in the future.
- NEWTEXTMETRICEXW text_metric = {};
- text_metric.ntmTm.ntmFlags = NTM_PS_OPENTYPE;
-
- return enum_callback(&enum_log_font.elfEnumLogfontEx.elfLogFont,
- reinterpret_cast<TEXTMETRIC*>(&text_metric),
- TRUETYPE_FONTTYPE, callback_param);
-}
-
-DWORD WINAPI GetFontDataPatch(HDC dc_handle,
- DWORD table_tag,
- DWORD table_offset,
- LPVOID buffer,
- DWORD buffer_length) {
- scoped_refptr<FakeGdiObject> dc_obj =
- g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
- if (!dc_obj)
- return GDI_ERROR;
-
- skia::RefPtr<SkTypeface> typeface = dc_obj->typeface();
- if (!typeface)
- return GDI_ERROR;
-
- // |getTableData| handles |buffer| being nullptr. However if it is nullptr
- // then set the size to INT32_MAX otherwise |getTableData| will return the
- // minimum value between the table entry size and the size passed in. The
- // common Windows idiom is to pass 0 as |buffer_length| when passing nullptr,
- // which would in this case result in |getTableData| returning 0 which isn't
- // the correct answer for emulating GDI. |table_tag| must also have its
- // byte order swapped to counter the swap which occurs in the called method.
- size_t length = typeface->getTableData(
- base::ByteSwap(base::strict_cast<uint32_t>(table_tag)), table_offset,
- buffer ? buffer_length : INT32_MAX, buffer);
- // We can't distinguish between an empty table and an error.
- if (length == 0)
- return GDI_ERROR;
-
- return base::checked_cast<DWORD>(length);
-}
-
-HGDIOBJ WINAPI SelectObjectPatch(HDC dc_handle, HGDIOBJ object_handle) {
- scoped_refptr<FakeGdiObject> dc_obj =
- g_fake_gdi_object_factory.Get().Validate(dc_handle, kFakeDCMagic);
- if (!dc_obj)
- return nullptr;
-
- scoped_refptr<FakeGdiObject> font_obj =
- g_fake_gdi_object_factory.Get().Validate(object_handle, kFakeFontMagic);
- if (!font_obj)
- return nullptr;
-
- // Construct a new fake font object to handle the old font if there's one.
- scoped_refptr<FakeGdiObject> new_font_obj;
- skia::RefPtr<SkTypeface> old_typeface = dc_obj->typeface();
- if (old_typeface) {
- new_font_obj = g_fake_gdi_object_factory.Get().Create(kFakeFontMagic);
- new_font_obj->set_typeface(old_typeface);
- }
- dc_obj->set_typeface(font_obj->typeface());
-
- if (new_font_obj)
- return static_cast<HGDIOBJ>(new_font_obj->handle());
- return nullptr;
-}
-
-void DoSingleGdiPatch(base::win::IATPatchFunction& patch,
- const base::FilePath& path,
- const char* function_name,
- void* new_function) {
- patch.Patch(path.value().c_str(), "gdi32.dll", function_name, new_function);
-}
-
-class GdiFontPatchDataImpl : public content::GdiFontPatchData {
- public:
- GdiFontPatchDataImpl(const base::FilePath& path);
-
- private:
- base::win::IATPatchFunction create_compatible_dc_patch_;
- base::win::IATPatchFunction create_font_indirect_patch_;
- base::win::IATPatchFunction create_delete_dc_patch_;
- base::win::IATPatchFunction create_delete_object_patch_;
- base::win::IATPatchFunction create_enum_font_families_patch_;
- base::win::IATPatchFunction create_get_font_data_patch_;
- base::win::IATPatchFunction create_select_object_patch_;
-};
-
-GdiFontPatchDataImpl::GdiFontPatchDataImpl(const base::FilePath& path) {
- DoSingleGdiPatch(create_compatible_dc_patch_, path, "CreateCompatibleDC",
- CreateCompatibleDCPatch);
- DoSingleGdiPatch(create_font_indirect_patch_, path, "CreateFontIndirectW",
- CreateFontIndirectWPatch);
- DoSingleGdiPatch(create_delete_dc_patch_, path, "DeleteDC", DeleteDCPatch);
- DoSingleGdiPatch(create_delete_object_patch_, path, "DeleteObject",
- DeleteObjectPatch);
- DoSingleGdiPatch(create_enum_font_families_patch_, path,
- "EnumFontFamiliesExW", EnumFontFamiliesExWPatch);
- DoSingleGdiPatch(create_get_font_data_patch_, path, "GetFontData",
- GetFontDataPatch);
- DoSingleGdiPatch(create_select_object_patch_, path, "SelectObject",
- SelectObjectPatch);
-}
-
-} // namespace
-
-// Directwrite connects to the font cache service to retrieve information about
-// fonts installed on the system etc. This works well outside the sandbox and
-// within the sandbox as long as the lpc connection maintained by the current
-// process with the font cache service remains valid. It appears that there
-// are cases when this connection is dropped after which directwrite is unable
-// to connect to the font cache service which causes problems with characters
-// disappearing.
-// Directwrite has fallback code to enumerate fonts if it is unable to connect
-// to the font cache service. We need to intercept the following APIs to
-// ensure that it does not connect to the font cache service.
-// NtALpcConnectPort
-// OpenSCManagerW
-// OpenServiceW
-// StartServiceW
-// CloseServiceHandle.
-// These are all IAT patched.
-void PatchServiceManagerCalls() {
- static bool is_patched = false;
- if (is_patched)
- return;
- const char* service_provider_dll =
- (base::win::GetVersion() >= base::win::VERSION_WIN8
- ? "api-ms-win-service-management-l1-1-0.dll"
- : "advapi32.dll");
-
- is_patched = true;
-
- DWORD patched =
- g_iat_patch_open_sc_manager.Patch(L"dwrite.dll", service_provider_dll,
- "OpenSCManagerW", OpenSCManagerWPatch);
- DCHECK(patched == 0);
-
- patched = g_iat_patch_close_service_handle.Patch(
- L"dwrite.dll", service_provider_dll, "CloseServiceHandle",
- CloseServiceHandlePatch);
- DCHECK(patched == 0);
-
- patched = g_iat_patch_open_service.Patch(L"dwrite.dll", service_provider_dll,
- "OpenServiceW", OpenServiceWPatch);
- DCHECK(patched == 0);
-
- patched = g_iat_patch_start_service.Patch(
- L"dwrite.dll", service_provider_dll, "StartServiceW", StartServiceWPatch);
- DCHECK(patched == 0);
-
- patched = g_iat_patch_nt_connect_port.Patch(
- L"dwrite.dll", "ntdll.dll", "NtAlpcConnectPort", NtALpcConnectPortPatch);
- DCHECK(patched == 0);
-}
-
-void DoPreSandboxWarmupForTypeface(SkTypeface* typeface) {
- SkPaint paint_warmup;
- paint_warmup.setTypeface(typeface);
- wchar_t glyph = L'S';
- paint_warmup.measureText(&glyph, 2);
-}
-
-SkFontMgr* GetPreSandboxWarmupFontMgr() {
- if (!g_warmup_fontmgr) {
- IDWriteFactory* factory;
- CreateDirectWriteFactory(&factory);
-
- GetCustomFontCollection(factory);
-
- PatchDWriteFactory(factory);
-
- blink::WebFontRendering::setDirectWriteFactory(factory);
- g_warmup_fontmgr = SkFontMgr_New_DirectWrite(factory);
- }
- return g_warmup_fontmgr;
-}
-
-GdiFontPatchData* PatchGdiFontEnumeration(const base::FilePath& path) {
- if (ShouldUseDirectWriteFontProxyFieldTrial() && !g_warmup_fontmgr)
- g_warmup_fontmgr = SkFontMgr_New_DirectWrite();
- // If not using the font proxy, we assume |g_warmup_fontmgr| is already
- // initialized before this function is called.
- DCHECK(g_warmup_fontmgr);
- return new GdiFontPatchDataImpl(path);
-}
-
-size_t GetEmulatedGdiHandleCountForTesting() {
- return g_fake_gdi_object_factory.Get().GetObjectCount();
-}
-
-void ResetEmulatedGdiHandlesForTesting() {
- g_fake_gdi_object_factory.Get().ResetObjectHandles();
-}
-
-void SetPreSandboxWarmupFontMgrForTesting(SkFontMgr* fontmgr) {
- g_warmup_fontmgr = fontmgr;
-}
-
-void WarmupDirectWrite() {
- TRACE_EVENT0("startup", "content::WarmupDirectWrite");
-
- // The objects used here are intentionally not freed as we want the Skia
- // code to use these objects after warmup.
- SetDefaultSkiaFactory(GetPreSandboxWarmupFontMgr());
-
- // We need to warm up *some* font for DirectWrite. Note that we don't use
- // a monospace as would be nice in an attempt to avoid a small startup time
- // regression, see http://crbug.com/463613.
- skia::RefPtr<SkTypeface> hud_typeface = skia::AdoptRef(
- GetPreSandboxWarmupFontMgr()->legacyCreateTypeface("Times New Roman", 0));
- DoPreSandboxWarmupForTypeface(hud_typeface.get());
-}
-
-} // namespace content
diff --git a/chromium/content/common/font_warmup_win.h b/chromium/content/common/font_warmup_win.h
deleted file mode 100644
index 8539b9ec0b2..00000000000
--- a/chromium/content/common/font_warmup_win.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_FONT_WARMUP_WIN_H_
-#define CONTENT_COMMON_FONT_WARMUP_WIN_H_
-
-#include <stddef.h>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-
-class SkFontMgr;
-class SkTypeface;
-
-namespace content {
-
-// Make necessary calls to cache the data for a given font, used before
-// sandbox lockdown.
-CONTENT_EXPORT void DoPreSandboxWarmupForTypeface(SkTypeface* typeface);
-
-// Get the shared font manager used during pre-sandbox warmup for DirectWrite
-// fonts.
-CONTENT_EXPORT SkFontMgr* GetPreSandboxWarmupFontMgr();
-
-class GdiFontPatchData {
- public:
- virtual ~GdiFontPatchData() {}
-
- protected:
- GdiFontPatchData() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GdiFontPatchData);
-};
-
-// Hook a module's imported GDI font functions to reimplement font enumeration
-// and font data retrieval for DLLs which can't be easily modified.
-CONTENT_EXPORT GdiFontPatchData* PatchGdiFontEnumeration(
- const base::FilePath& path);
-
-// Testing method to get the number of in-flight emulated GDI handles.
-CONTENT_EXPORT size_t GetEmulatedGdiHandleCountForTesting();
-
-// Testing method to reset the table of emulated GDI handles.
-CONTENT_EXPORT void ResetEmulatedGdiHandlesForTesting();
-
-// Sets the pre-sandbox warmup font manager directly. This should only be used
-// for testing the implementation.
-CONTENT_EXPORT void SetPreSandboxWarmupFontMgrForTesting(SkFontMgr* fontmgr);
-
-// Warmup the direct write font manager for content processes.
-CONTENT_EXPORT void WarmupDirectWrite();
-
-// Directwrite connects to the font cache service to retrieve information about
-// fonts installed on the system etc. This works well outside the sandbox and
-// within the sandbox as long as the lpc connection maintained by the current
-// process with the font cache service remains valid. It appears that there
-// are cases when this connection is dropped after which directwrite is unable
-// to connect to the font cache service which causes problems with characters
-// disappearing.
-// Directwrite has fallback code to enumerate fonts if it is unable to connect
-// to the font cache service. We need to intercept the following APIs to
-// ensure that it does not connect to the font cache service.
-// NtALpcConnectPort
-// OpenSCManagerW
-// OpenServiceW
-// StartServiceW
-// CloseServiceHandle.
-// These are all IAT patched.
-CONTENT_EXPORT void PatchServiceManagerCalls();
-
-} // namespace content
-
-#endif // CONTENT_COMMON_FONT_WARMUP_WIN_H_
diff --git a/chromium/content/common/font_warmup_win_unittest.cc b/chromium/content/common/font_warmup_win_unittest.cc
deleted file mode 100644
index 362373fd25f..00000000000
--- a/chromium/content/common/font_warmup_win_unittest.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2015 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 "content/common/font_warmup_win.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/sys_byteorder.h"
-#include "base/win/windows_version.h"
-#include "skia/ext/refptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkString.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
-
-namespace content {
-
-namespace {
-
-class TestSkTypeface : public SkTypeface {
- public:
- TestSkTypeface(const SkFontStyle& style,
- const char* familyName,
- SkFontTableTag tag,
- const char* data,
- size_t dataLength)
- : SkTypeface(style, 0),
- familyName_(familyName),
- tag_(tag),
- data_(data, data + dataLength) {}
-
- protected:
- SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override {
- ADD_FAILURE();
- return nullptr;
- }
- void onFilterRec(SkScalerContextRec*) const override { ADD_FAILURE(); }
- SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
- PerGlyphInfo,
- const uint32_t* glyphIDs,
- uint32_t glyphIDsCount) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkStreamAsset* onOpenStream(int* ttcIndex) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkFontData* onCreateFontData() const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override {
- ADD_FAILURE();
- }
-
- int onCharsToGlyphs(const void* chars,
- Encoding,
- uint16_t glyphs[],
- int glyphCount) const override {
- ADD_FAILURE();
- return 0;
- }
-
- int onCountGlyphs() const override {
- ADD_FAILURE();
- return 0;
- }
-
- int onGetUPEM() const override {
- ADD_FAILURE();
- return 0;
- }
- bool onGetKerningPairAdjustments(const uint16_t glyphs[],
- int count,
- int32_t adjustments[]) const override {
- ADD_FAILURE();
- return false;
- }
-
- void onGetFamilyName(SkString* familyName) const override {
- *familyName = familyName_;
- }
-
- LocalizedStrings* onCreateFamilyNameIterator() const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- int onGetTableTags(SkFontTableTag tags[]) const override {
- ADD_FAILURE();
- return 0;
- }
-
- size_t onGetTableData(SkFontTableTag tag,
- size_t offset,
- size_t length,
- void* data) const override {
- size_t retsize = 0;
- if (tag == tag_) {
- retsize = length > data_.size() ? data_.size() : length;
- if (data)
- memcpy(data, &data_[0], retsize);
- }
- return retsize;
- }
-
- bool onComputeBounds(SkRect*) const override {
- ADD_FAILURE();
- return false;
- }
-
- private:
- SkString familyName_;
- SkFontTableTag tag_;
- std::vector<char> data_;
-};
-
-const char* kTestFontFamily = "GDITest";
-const wchar_t* kTestFontFamilyW = L"GDITest";
-const SkFontTableTag kTestFontTableTag = 0x11223344;
-const char* kTestFontData = "GDITestGDITest";
-const wchar_t* kTestFontFamilyInvalid = L"InvalidFont";
-
-class TestSkFontMgr : public SkFontMgr {
- public:
- TestSkFontMgr() { content::SetPreSandboxWarmupFontMgrForTesting(this); }
- ~TestSkFontMgr() override {
- content::SetPreSandboxWarmupFontMgrForTesting(nullptr);
- }
-
- protected:
- int onCountFamilies() const override { return 1; }
-
- void onGetFamilyName(int index, SkString* familyName) const override {
- if (index == 0)
- *familyName = kTestFontFamily;
- }
-
- SkFontStyleSet* onCreateStyleSet(int index) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onMatchFamilyStyle(const char familyName[],
- const SkFontStyle&) const override {
- if (strcmp(familyName, kTestFontFamily) == 0)
- return createTypeface();
- return nullptr;
- }
-
- SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
- const SkFontStyle&,
- const char* bcp47[],
- int bcp47Count,
- SkUnichar character) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onMatchFaceStyle(const SkTypeface*,
- const SkFontStyle&) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onCreateFromData(SkData*, int ttcIndex) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onCreateFromStream(SkStreamAsset*, int ttcIndex) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onCreateFromFontData(SkFontData*) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- SkTypeface* onLegacyCreateTypeface(const char familyName[],
- unsigned styleBits) const override {
- ADD_FAILURE();
- return nullptr;
- }
-
- private:
- SkTypeface* createTypeface() const {
- SkFontStyle style(400, 100, SkFontStyle::kUpright_Slant);
-
- return new TestSkTypeface(style, kTestFontFamily,
- base::ByteSwap(kTestFontTableTag), kTestFontData,
- strlen(kTestFontData));
- }
-};
-
-void InitLogFont(LOGFONTW* logfont, const wchar_t* fontname) {
- size_t length = std::min(sizeof(logfont->lfFaceName),
- (wcslen(fontname) + 1) * sizeof(wchar_t));
- memcpy(logfont->lfFaceName, fontname, length);
-}
-
-content::GdiFontPatchData* SetupTest() {
- HMODULE module_handle;
- if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- reinterpret_cast<LPCWSTR>(SetupTest),
- &module_handle)) {
- WCHAR module_path[MAX_PATH];
-
- if (GetModuleFileNameW(module_handle, module_path, MAX_PATH) > 0) {
- base::FilePath path(module_path);
- content::ResetEmulatedGdiHandlesForTesting();
- return content::PatchGdiFontEnumeration(path);
- }
- }
- return nullptr;
-}
-
-int CALLBACK EnumFontCallbackTest(const LOGFONT* log_font,
- const TEXTMETRIC* text_metric,
- DWORD font_type,
- LPARAM param) {
- const NEWTEXTMETRICEX* new_text_metric =
- reinterpret_cast<const NEWTEXTMETRICEX*>(text_metric);
-
- return !(font_type & TRUETYPE_FONTTYPE) &&
- !(new_text_metric->ntmTm.ntmFlags & NTM_PS_OPENTYPE);
-}
-
-} // namespace
-
-TEST(GDIFontEmulationTest, CreateDeleteDCSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_FALSE(!patch_data);
-
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- EXPECT_EQ(1u, GetEmulatedGdiHandleCountForTesting());
- EXPECT_TRUE(DeleteDC(hdc));
- EXPECT_EQ(0u, GetEmulatedGdiHandleCountForTesting());
-}
-
-TEST(GDIFontEmulationTest, CreateUniqueDCSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
-
- HDC hdc1 = CreateCompatibleDC(0);
- EXPECT_NE(hdc1, nullptr);
- HDC hdc2 = CreateCompatibleDC(0);
- EXPECT_NE(hdc2, nullptr);
- EXPECT_NE(hdc1, hdc2);
- EXPECT_TRUE(DeleteDC(hdc2));
- EXPECT_EQ(1u, GetEmulatedGdiHandleCountForTesting());
- EXPECT_TRUE(DeleteDC(hdc1));
- EXPECT_EQ(0u, GetEmulatedGdiHandleCountForTesting());
-}
-
-TEST(GDIFontEmulationTest, CreateFontSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyW);
- HFONT font = CreateFontIndirectW(&logfont);
- EXPECT_NE(font, nullptr);
- EXPECT_TRUE(DeleteObject(font));
- EXPECT_EQ(0u, GetEmulatedGdiHandleCountForTesting());
-}
-
-TEST(GDIFontEmulationTest, CreateFontFailure) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyInvalid);
- HFONT font = CreateFontIndirectW(&logfont);
- EXPECT_EQ(font, nullptr);
-}
-
-TEST(GDIFontEmulationTest, EnumFontFamilySuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyW);
- int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
- EXPECT_FALSE(res);
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, EnumFontFamilyFailure) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyInvalid);
- int res = EnumFontFamiliesExW(hdc, &logfont, EnumFontCallbackTest, 0, 0);
- EXPECT_TRUE(res);
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, DeleteDCFailure) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = reinterpret_cast<HDC>(0x55667788);
- EXPECT_FALSE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, DeleteObjectFailure) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HFONT font = reinterpret_cast<HFONT>(0x88aabbcc);
- EXPECT_FALSE(DeleteObject(font));
-}
-
-TEST(GDIFontEmulationTest, GetFontDataSizeSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyW);
- HFONT font = CreateFontIndirectW(&logfont);
- EXPECT_NE(font, nullptr);
- EXPECT_EQ(SelectObject(hdc, font), nullptr);
- DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
- DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
- EXPECT_EQ(size, data_size);
- EXPECT_TRUE(DeleteObject(font));
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, GetFontDataInvalidTagSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyW);
- HFONT font = CreateFontIndirectW(&logfont);
- EXPECT_NE(font, nullptr);
- EXPECT_EQ(SelectObject(hdc, font), nullptr);
- DWORD size = GetFontData(hdc, kTestFontTableTag + 1, 0, nullptr, 0);
- EXPECT_EQ(size, GDI_ERROR);
- EXPECT_TRUE(DeleteObject(font));
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, GetFontDataInvalidFontSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- DWORD size = GetFontData(hdc, kTestFontTableTag, 0, nullptr, 0);
- EXPECT_EQ(size, GDI_ERROR);
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-TEST(GDIFontEmulationTest, GetFontDataDataSuccess) {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return;
- TestSkFontMgr fontmgr;
- scoped_ptr<GdiFontPatchData> patch_data(SetupTest());
- EXPECT_NE(patch_data, nullptr);
- HDC hdc = CreateCompatibleDC(0);
- EXPECT_NE(hdc, nullptr);
- LOGFONTW logfont = {0};
- InitLogFont(&logfont, kTestFontFamilyW);
- HFONT font = CreateFontIndirectW(&logfont);
- EXPECT_NE(font, nullptr);
- EXPECT_EQ(SelectObject(hdc, font), nullptr);
- DWORD data_size = static_cast<DWORD>(strlen(kTestFontData));
- std::vector<char> data(data_size);
- DWORD size = GetFontData(hdc, kTestFontTableTag, 0, &data[0], data.size());
- EXPECT_EQ(size, data_size);
- EXPECT_EQ(memcmp(&data[0], kTestFontData, data.size()), 0);
- EXPECT_TRUE(DeleteObject(font));
- EXPECT_TRUE(DeleteDC(hdc));
-}
-
-} // namespace content
diff --git a/chromium/content/common/frame_message_enums.h b/chromium/content/common/frame_message_enums.h
index b93120607f5..27e98433c75 100644
--- a/chromium/content/common/frame_message_enums.h
+++ b/chromium/content/common/frame_message_enums.h
@@ -10,11 +10,11 @@
struct FrameMsg_Navigate_Type {
public:
enum Value {
- // Reload the page.
+ // Reload the page, validating cache entries.
RELOAD,
- // Reload the page, ignoring any cache entries.
- RELOAD_IGNORING_CACHE,
+ // Reload the page, bypassing any cache entries.
+ RELOAD_BYPASSING_CACHE,
// Reload the page using the original request URL.
RELOAD_ORIGINAL_REQUEST_URL,
diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h
index 18892e8df15..7d1f562997a 100644
--- a/chromium/content/common/frame_messages.h
+++ b/chromium/content/common/frame_messages.h
@@ -19,7 +19,6 @@
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
#include "content/common/frame_message_enums.h"
-#include "content/common/frame_param.h"
#include "content/common/frame_replication_state.h"
#include "content/common/navigation_gesture.h"
#include "content/common/navigation_params.h"
@@ -35,14 +34,19 @@
#include "content/public/common/page_importance_signals.h"
#include "content/public/common/page_state.h"
#include "content/public/common/resource_response.h"
+#include "content/public/common/stop_find_action.h"
#include "content/public/common/three_d_api_types.h"
#include "content/public/common/transition_element.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
+#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebTreeScopeType.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -54,8 +58,10 @@
#ifndef CONTENT_COMMON_FRAME_MESSAGES_H_
#define CONTENT_COMMON_FRAME_MESSAGES_H_
-using FrameMsg_GetSerializedHtmlWithLocalLinks_Map =
+using FrameMsg_GetSerializedHtmlWithLocalLinks_UrlMap =
std::map<GURL, base::FilePath>;
+using FrameMsg_GetSerializedHtmlWithLocalLinks_FrameRoutingIdMap =
+ std::map<int, base::FilePath>;
using FrameMsg_SerializeAsMHTML_FrameRoutingIdToContentIdMap =
std::map<int, std::string>;
@@ -84,6 +90,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContextMenuData::InputFieldType,
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFocusType, blink::WebFocusTypeLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFrameOwnerProperties::ScrollingMode,
blink::WebFrameOwnerProperties::ScrollingMode::Last)
+IPC_ENUM_TRAITS_MAX_VALUE(content::StopFindAction,
+ content::STOP_FIND_ACTION_LAST)
IPC_ENUM_TRAITS(blink::WebSandboxFlags) // Bitmask.
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTreeScopeType,
blink::WebTreeScopeType::Last)
@@ -92,6 +100,12 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(content::LoFiState,
content::LOFI_UNSPECIFIED,
content::LOFI_ON)
+IPC_STRUCT_TRAITS_BEGIN(blink::WebFindOptions)
+ IPC_STRUCT_TRAITS_MEMBER(forward)
+ IPC_STRUCT_TRAITS_MEMBER(matchCase)
+ IPC_STRUCT_TRAITS_MEMBER(findNext)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::ColorSuggestion)
IPC_STRUCT_TRAITS_MEMBER(color)
IPC_STRUCT_TRAITS_MEMBER(label)
@@ -208,6 +222,9 @@ IPC_STRUCT_BEGIN_WITH_PARENT(FrameHostMsg_DidCommitProvisionalLoad_Params,
// Whether this commit created a new entry.
IPC_STRUCT_MEMBER(bool, did_create_new_entry)
+ // Whether this commit should replace the current entry.
+ IPC_STRUCT_MEMBER(bool, should_replace_current_entry)
+
// Information regarding the security of the connection (empty if the
// connection was not secure).
IPC_STRUCT_MEMBER(std::string, security_info)
@@ -274,6 +291,13 @@ IPC_STRUCT_BEGIN_WITH_PARENT(FrameHostMsg_DidCommitProvisionalLoad_Params,
// True if the document for the load is enforcing strict mixed content
// checking.
IPC_STRUCT_MEMBER(bool, should_enforce_strict_mixed_content_checking)
+
+ // True if the document for the load is a unique origin that should be
+ // considered potentially trustworthy.
+ IPC_STRUCT_MEMBER(bool, has_potentially_trustworthy_unique_origin)
+
+ // True if the navigation originated as an srcdoc attribute.
+ IPC_STRUCT_MEMBER(bool, is_srcdoc)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(FrameMsg_PostMessage_Params)
@@ -314,10 +338,10 @@ IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(history_url_for_data_url)
IPC_STRUCT_TRAITS_MEMBER(lofi_state)
IPC_STRUCT_TRAITS_MEMBER(navigation_start)
+ IPC_STRUCT_TRAITS_MEMBER(method)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams)
- IPC_STRUCT_TRAITS_MEMBER(method)
IPC_STRUCT_TRAITS_MEMBER(headers)
IPC_STRUCT_TRAITS_MEMBER(load_flags)
IPC_STRUCT_TRAITS_MEMBER(has_user_gesture)
@@ -326,7 +350,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::StartNavigationParams)
- IPC_STRUCT_TRAITS_MEMBER(is_post)
IPC_STRUCT_TRAITS_MEMBER(extra_headers)
IPC_STRUCT_TRAITS_MEMBER(browser_initiated_post_data)
#if defined(OS_ANDROID)
@@ -363,6 +386,10 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameReplicationState)
IPC_STRUCT_TRAITS_MEMBER(origin)
IPC_STRUCT_TRAITS_MEMBER(sandbox_flags)
IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(unique_name)
+ IPC_STRUCT_TRAITS_MEMBER(scope)
+ IPC_STRUCT_TRAITS_MEMBER(should_enforce_strict_mixed_content_checking)
+ IPC_STRUCT_TRAITS_MEMBER(has_potentially_trustworthy_unique_origin)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_BEGIN(FrameMsg_NewFrame_WidgetParams)
@@ -490,6 +517,26 @@ IPC_STRUCT_BEGIN(FrameMsg_SerializeAsMHTML_Params)
IPC_STRUCT_MEMBER(bool, is_last_frame)
IPC_STRUCT_END()
+// This message is used to send hittesting data from the renderer in order
+// to perform hittesting on the browser process.
+IPC_STRUCT_BEGIN(FrameHostMsg_HittestData_Params)
+ // |surface_id| represents the surface used by this remote frame.
+ IPC_STRUCT_MEMBER(cc::SurfaceId, surface_id)
+
+ // If |ignored_for_hittest| then this surface should be ignored during
+ // hittesting.
+ IPC_STRUCT_MEMBER(bool, ignored_for_hittest)
+IPC_STRUCT_END()
+
+IPC_STRUCT_BEGIN(FrameHostMsg_CreateChildFrame_Params)
+ IPC_STRUCT_MEMBER(int32_t, parent_routing_id)
+ IPC_STRUCT_MEMBER(blink::WebTreeScopeType, scope)
+ IPC_STRUCT_MEMBER(std::string, frame_name)
+ IPC_STRUCT_MEMBER(std::string, frame_unique_name)
+ IPC_STRUCT_MEMBER(blink::WebSandboxFlags, sandbox_flags)
+ IPC_STRUCT_MEMBER(blink::WebFrameOwnerProperties, frame_owner_properties)
+IPC_STRUCT_END()
+
#if defined(OS_MACOSX) || defined(OS_ANDROID)
// This message is used for supporting popup menus on Mac OS X and Android using
// native controls. See the FrameHostMsg_ShowPopup message.
@@ -530,15 +577,6 @@ IPC_STRUCT_TRAITS_END()
// -----------------------------------------------------------------------------
// Messages sent from the browser to the renderer.
-// Notifies the embedding frame that a new CompositorFrame is ready to be
-// presented. When the frame finishes presenting, a matching
-// FrameHostMsg_CompositorFrameSwappedACK should be sent back to the
-// RenderViewHost that was produced the CompositorFrame.
-//
-// This is used in the ubercomp compositing path.
-IPC_MESSAGE_ROUTED1(FrameMsg_CompositorFrameSwapped,
- FrameMsg_CompositorFrameSwapped_Params /* params */)
-
IPC_MESSAGE_ROUTED4(FrameMsg_SetChildFrameSurface,
cc::SurfaceId /* surface_id */,
gfx::Size /* frame_size */,
@@ -554,6 +592,10 @@ IPC_MESSAGE_ROUTED0(FrameMsg_ChildFrameProcessGone)
IPC_MESSAGE_ROUTED1(FrameMsg_ContextMenuClosed,
content::CustomContextMenuContext /* custom_context */)
+// Reloads all the Lo-Fi images in the RenderFrame. Ignores the cache and
+// reloads from the network.
+IPC_MESSAGE_ROUTED0(FrameMsg_ReloadLoFiImages)
+
// Executes custom context menu action that was provided from Blink.
IPC_MESSAGE_ROUTED2(FrameMsg_CustomContextMenuAction,
content::CustomContextMenuContext /* custom_context */,
@@ -685,10 +727,10 @@ IPC_MESSAGE_ROUTED1(FrameMsg_HideTransitionElements,
IPC_MESSAGE_ROUTED1(FrameMsg_ShowTransitionElements,
std::string /* css_selector */)
-// Tells the renderer to reload the frame, optionally ignoring the cache while
+// Tells the renderer to reload the frame, optionally bypassing the cache while
// doing so.
IPC_MESSAGE_ROUTED1(FrameMsg_Reload,
- bool /* ignore_cache */)
+ bool /* bypass_cache */)
// Notifies the color chooser client that the user selected a color.
IPC_MESSAGE_ROUTED2(FrameMsg_DidChooseColorResponse, unsigned, SkColor)
@@ -703,7 +745,7 @@ IPC_MESSAGE_ROUTED0(FrameMsg_DeleteProxy)
// Request the text surrounding the selection with a |max_length|. The response
// will be sent via FrameHostMsg_TextSurroundingSelectionResponse.
IPC_MESSAGE_ROUTED1(FrameMsg_TextSurroundingSelectionRequest,
- size_t /* max_length */)
+ uint32_t /* max_length */)
// Tells the renderer to insert a link to the specified stylesheet. This is
// needed to support navigation transitions.
@@ -721,7 +763,9 @@ IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateSandboxFlags, blink::WebSandboxFlags)
// Update a proxy's window.name property. Used when the frame's name is
// changed in another process.
-IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateName, std::string /* name */)
+IPC_MESSAGE_ROUTED2(FrameMsg_DidUpdateName,
+ std::string /* name */,
+ std::string /* unique_name */)
// Update a proxy's replicated enforcement of strict mixed content
// checking. Used when the frame's mixed content setting is changed in
@@ -731,7 +775,9 @@ IPC_MESSAGE_ROUTED1(FrameMsg_EnforceStrictMixedContentChecking,
// Update a proxy's replicated origin. Used when the frame is navigated to a
// new origin.
-IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateOrigin, url::Origin /* origin */)
+IPC_MESSAGE_ROUTED2(FrameMsg_DidUpdateOrigin,
+ url::Origin /* origin */,
+ bool /* is potentially trustworthy unique origin */)
// Notifies this frame or proxy that it is now focused. This is used to
// support cross-process focused frame changes.
@@ -746,6 +792,17 @@ IPC_MESSAGE_ROUTED1(FrameMsg_SetTextTrackSettings,
IPC_MESSAGE_ROUTED1(FrameMsg_PostMessageEvent, FrameMsg_PostMessage_Params)
#if defined(OS_ANDROID)
+// Sent when the browser wants the bounding boxes of the current find matches.
+//
+// If match rects are already cached on the browser side, |current_version|
+// should be the version number from the FrameHostMsg_FindMatchRects_Reply
+// they came in, so the renderer can tell if it needs to send updated rects.
+// Otherwise just pass -1 to always receive the list of rects.
+//
+// There must be an active search string (it is probably most useful to call
+// this immediately after a FrameHostMsg_Find_Reply message arrives with
+// final_update set to true).
+IPC_MESSAGE_ROUTED1(FrameMsg_FindMatchRects, int /* current_version */)
// External popup menus.
IPC_MESSAGE_ROUTED2(FrameMsg_SelectPopupMenuItems,
@@ -785,8 +842,9 @@ IPC_MESSAGE_ROUTED0(FrameMsg_GetSavableResourceLinks)
// Get html data by serializing the target frame and replacing all resource
// links with a path to the local copy passed in the message payload.
-IPC_MESSAGE_ROUTED1(FrameMsg_GetSerializedHtmlWithLocalLinks,
- FrameMsg_GetSerializedHtmlWithLocalLinks_Map)
+IPC_MESSAGE_ROUTED2(FrameMsg_GetSerializedHtmlWithLocalLinks,
+ FrameMsg_GetSerializedHtmlWithLocalLinks_UrlMap,
+ FrameMsg_GetSerializedHtmlWithLocalLinks_FrameRoutingIdMap)
// Serialize target frame and its resources into MHTML and write it into the
// provided destination file handle. Note that when serializing multiple
@@ -806,12 +864,30 @@ IPC_MESSAGE_ROUTED2(FrameMsg_AdvanceFocus,
blink::WebFocusType /* type */,
int32_t /* source_routing_id */)
+// Sent when the user wants to search for a word on the page (find-in-page).
+IPC_MESSAGE_ROUTED3(FrameMsg_Find,
+ int /* request_id */,
+ base::string16 /* search_text */,
+ blink::WebFindOptions)
+
+// This message notifies the renderer that the user has closed the find-in-page
+// window (and what action to take regarding the selection).
+IPC_MESSAGE_ROUTED1(FrameMsg_StopFinding, content::StopFindAction /* action */)
+
#if defined(ENABLE_PLUGINS)
// Notifies the renderer of updates to the Plugin Power Saver origin whitelist.
IPC_MESSAGE_ROUTED1(FrameMsg_UpdatePluginContentOriginWhitelist,
std::set<url::Origin> /* origin_whitelist */)
#endif // defined(ENABLE_PLUGINS)
+// Used to instruct the RenderFrame to go into "view source" mode. This should
+// only be sent to the main frame.
+IPC_MESSAGE_ROUTED0(FrameMsg_EnableViewSourceMode)
+
+// Tells the frame to suppress any further modal dialogs. This ensures that no
+// ScopedPageLoadDeferrer is on the stack for SwapOut.
+IPC_MESSAGE_ROUTED0(FrameMsg_SuppressFurtherDialogs)
+
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
@@ -827,14 +903,9 @@ IPC_MESSAGE_ROUTED4(FrameHostMsg_AddMessageToConsole,
//
// Each of these messages will have a corresponding FrameHostMsg_Detach message
// sent when the frame is detached from the DOM.
-IPC_SYNC_MESSAGE_CONTROL5_1(
- FrameHostMsg_CreateChildFrame,
- int32_t /* parent_routing_id */,
- blink::WebTreeScopeType /* scope */,
- std::string /* frame_name */,
- blink::WebSandboxFlags /* sandbox flags */,
- blink::WebFrameOwnerProperties /* frame_owner_properties */,
- int32_t /* new_routing_id */)
+IPC_SYNC_MESSAGE_CONTROL1_1(FrameHostMsg_CreateChildFrame,
+ FrameHostMsg_CreateChildFrame_Params,
+ int32_t /* new_routing_id */)
// Sent by the renderer to the parent RenderFrameHost when a child frame is
// detached from the DOM.
@@ -873,9 +944,6 @@ IPC_MESSAGE_ROUTED4(FrameHostMsg_DidFailLoadWithError,
base::string16 /* error_description */,
bool /* was_ignored_by_handler */)
-// Sent when the renderer decides to ignore a navigation.
-IPC_MESSAGE_ROUTED0(FrameHostMsg_DidDropNavigation)
-
// Sent when the renderer starts loading the page. |to_different_document| will
// be true unless the load is a fragment navigation, or triggered by
// history.pushState/replaceState.
@@ -889,7 +957,9 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_DidStopLoading)
IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateState, content::PageState /* state */)
// Sent when the frame changes its window.name.
-IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeName, std::string /* name */)
+IPC_MESSAGE_ROUTED2(FrameHostMsg_DidChangeName,
+ std::string /* name */,
+ std::string /* unique_name */)
// Sent when the frame starts enforcing strict mixed content
// checking. Sending this information in DidCommitProvisionalLoad isn't
@@ -898,6 +968,13 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeName, std::string /* name */)
// checking to be enforced.
IPC_MESSAGE_ROUTED0(FrameHostMsg_EnforceStrictMixedContentChecking)
+// Sent when the frame is set to a unique origin. TODO(estark): this IPC
+// only exists to support dynamic sandboxing via a CSP delivered in a
+// <meta> tag. This is not supposed to be allowed per the CSP spec and
+// should be ripped out. https://crbug.com/594645
+IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateToUniqueOrigin,
+ bool /* is potentially trustworthy unique origin */)
+
// Sent when the renderer changed the progress of a load.
IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeLoadProgress,
double /* load_progress */)
@@ -994,14 +1071,6 @@ IPC_SYNC_MESSAGE_CONTROL3_1(FrameHostMsg_Are3DAPIsBlocked,
content::ThreeDAPIType /* requester */,
bool /* blocked */)
-// Sent by the renderer process to indicate that a context was lost by
-// client 3D content (Pepper 3D, WebGL) running on the page at the
-// given URL.
-IPC_MESSAGE_CONTROL3(FrameHostMsg_DidLose3DContext,
- GURL /* top_origin_url */,
- content::ThreeDAPIType /* context_type */,
- int /* arb_robustness_status_code */)
-
#if defined(ENABLE_PLUGINS)
// Notification sent from a renderer to the browser that a Pepper plugin
// instance is created in the DOM.
@@ -1054,18 +1123,6 @@ IPC_SYNC_MESSAGE_CONTROL4_3(FrameHostMsg_GetPluginInfo,
IPC_MESSAGE_ROUTED1(FrameHostMsg_PluginContentOriginAllowed,
url::Origin /* content_origin */)
-// A renderer sends this to the browser process when it wants to
-// create a plugin. The browser will create the plugin process if
-// necessary, and will return a handle to the channel on success.
-// On error an empty string is returned.
-IPC_SYNC_MESSAGE_CONTROL4_2(FrameHostMsg_OpenChannelToPlugin,
- int /* render_frame_id */,
- GURL /* url */,
- GURL /* page_url */,
- std::string /* mime_type */,
- IPC::ChannelHandle /* channel_handle */,
- content::WebPluginInfo /* info */)
-
// A renderer sends this to the browser process when it wants to create a ppapi
// plugin. The browser will create the plugin process if necessary, and will
// return a handle to the channel on success.
@@ -1138,12 +1195,6 @@ IPC_MESSAGE_CONTROL3(FrameHostMsg_PluginInstanceThrottleStateChange,
bool /* is_throttled */)
#endif // defined(ENABLE_PLUGINS)
-// Acknowledge that we presented an ubercomp frame.
-//
-// See FrameMsg_CompositorFrameSwapped
-IPC_MESSAGE_ROUTED1(FrameHostMsg_CompositorFrameSwappedACK,
- FrameHostMsg_CompositorFrameSwappedACK_Params /* params */)
-
// Satisfies a Surface destruction dependency associated with |sequence|.
IPC_MESSAGE_ROUTED1(FrameHostMsg_SatisfySequence,
cc::SurfaceSequence /* sequence */)
@@ -1165,9 +1216,6 @@ IPC_MESSAGE_ROUTED3(FrameHostMsg_BeforeUnload_ACK,
// Indicates that the current frame has swapped out, after a SwapOut message.
IPC_MESSAGE_ROUTED0(FrameHostMsg_SwapOut_ACK)
-IPC_MESSAGE_ROUTED1(FrameHostMsg_ReclaimCompositorResources,
- FrameHostMsg_ReclaimCompositorResources_Params /* params */)
-
// Forwards an input event to a child.
// TODO(nick): Temporary bridge, revisit once the browser process can route
// input directly to subframes. http://crbug.com/339659
@@ -1214,9 +1262,8 @@ IPC_SYNC_MESSAGE_ROUTED4_2(FrameHostMsg_RunJavaScriptMessage,
// Displays a dialog to confirm that the user wants to navigate away from the
// page. Replies true if yes, and false otherwise. The reply string is ignored,
// but is included so that we can use OnJavaScriptMessageBoxClosed.
-IPC_SYNC_MESSAGE_ROUTED3_2(FrameHostMsg_RunBeforeUnloadConfirm,
+IPC_SYNC_MESSAGE_ROUTED2_2(FrameHostMsg_RunBeforeUnloadConfirm,
GURL, /* in - originating frame URL */
- base::string16 /* in - alert message */,
bool /* in - is a reload */,
bool /* out - success */,
base::string16 /* out - This is ignored.*/)
@@ -1235,16 +1282,6 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_SetSelectedColorInColorChooser,
int /* id */,
SkColor /* color */)
-// Notifies the browser that media has started/stopped playing.
-IPC_MESSAGE_ROUTED4(FrameHostMsg_MediaPlayingNotification,
- int64_t /* player_cookie, distinguishes instances */,
- bool /* has_video */,
- bool /* has_audio */,
- bool /* is_remote */)
-
-IPC_MESSAGE_ROUTED1(FrameHostMsg_MediaPausedNotification,
- int64_t /* player_cookie, distinguishes instances */)
-
// Notify browser the theme color has been changed.
IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeThemeColor,
SkColor /* theme_color */)
@@ -1253,8 +1290,8 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeThemeColor,
// |endOffset| are the offsets of the selection in the returned |content|.
IPC_MESSAGE_ROUTED3(FrameHostMsg_TextSurroundingSelectionResponse,
base::string16, /* content */
- size_t, /* startOffset */
- size_t /* endOffset */)
+ uint32_t, /* startOffset */
+ uint32_t/* endOffset */)
// Register a new handler for URL requests with the given scheme.
IPC_MESSAGE_ROUTED4(FrameHostMsg_RegisterProtocolHandler,
@@ -1361,6 +1398,22 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_AdvanceFocus,
blink::WebFocusType /* type */,
int32_t /* source_routing_id */)
+// Result of string search in the document.
+// Response to FrameMsg_Find with the results of the requested find-in-page
+// search, the number of matches found and the selection rect (in screen
+// coordinates) for the string found. If |final_update| is false, it signals
+// that this is not the last Find_Reply message - more will be sent as the
+// scoping effort continues.
+IPC_MESSAGE_ROUTED5(FrameHostMsg_Find_Reply,
+ int /* request_id */,
+ int /* number of matches */,
+ gfx::Rect /* selection_rect */,
+ int /* active_match_ordinal */,
+ bool /* final_update */)
+
+// Sends hittesting data needed to perform hittesting on the browser process.
+IPC_MESSAGE_ROUTED1(FrameHostMsg_HittestData, FrameHostMsg_HittestData_Params)
+
#if defined(OS_MACOSX) || defined(OS_ANDROID)
// Message to show/hide a popup menu using native controls.
@@ -1370,6 +1423,28 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_HidePopup)
#endif
+#if defined(OS_ANDROID)
+// Response to FrameMsg_FindMatchRects.
+//
+// |version| will contain the current version number of the renderer's find
+// match list (incremented whenever they change), which should be passed in the
+// next call to FrameMsg_FindMatchRects.
+//
+// |rects| will either contain a list of the enclosing rects of all matches
+// found by the most recent Find operation, or will be empty if |version| is not
+// greater than the |current_version| passed to FrameMsg_FindMatchRects (hence
+// your locally cached rects should still be valid). The rect coords will be
+// custom normalized fractions of the document size. The rects will be sorted by
+// frame traversal order starting in the main frame, then by dom order.
+//
+// |active_rect| will contain the bounding box of the active find-in-page match
+// marker, in similarly normalized coords (or an empty rect if there isn't one).
+IPC_MESSAGE_ROUTED3(FrameHostMsg_FindMatchRects_Reply,
+ int /* version */,
+ std::vector<gfx::RectF> /* rects */,
+ gfx::RectF /* active_rect */)
+#endif
+
// Adding a new message? Stick to the sort order above: first platform
// independent FrameMsg, then ifdefs for platform specific FrameMsg, then
// platform independent FrameHostMsg, then ifdefs for platform specific
diff --git a/chromium/content/common/frame_param.cc b/chromium/content/common/frame_param.cc
deleted file mode 100644
index dbeaaa72023..00000000000
--- a/chromium/content/common/frame_param.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 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 "content/common/frame_param.h"
-#include "content/common/cc_messages.h"
-
-#define IPC_MESSAGE_IMPL
-#include "content/common/frame_param_macros.h"
-
-// Generate constructors.
-#include "ipc/struct_constructor_macros.h"
-#undef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#include "content/common/frame_param_macros.h"
-
-// Generate destructors.
-#include "ipc/struct_destructor_macros.h"
-#undef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#include "content/common/frame_param_macros.h"
-
-// Generate param traits write methods.
-#include "ipc/param_traits_write_macros.h"
-namespace IPC {
-#undef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#include "content/common/frame_param_macros.h"
-} // namespace IPC
-
-// Generate param traits read methods.
-#include "ipc/param_traits_read_macros.h"
-namespace IPC {
-#undef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#include "content/common/frame_param_macros.h"
-} // namespace IPC
-
-// Generate param traits log methods.
-#include "ipc/param_traits_log_macros.h"
-namespace IPC {
-#undef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#include "content/common/frame_param_macros.h"
-} // namespace IPC
diff --git a/chromium/content/common/frame_param.h b/chromium/content/common/frame_param.h
deleted file mode 100644
index 29c4010d2aa..00000000000
--- a/chromium/content/common/frame_param.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_FRAME_PARAM_H_
-#define CONTENT_COMMON_FRAME_PARAM_H_
-
-#include "content/common/frame_param_macros.h"
-
-#endif // CONTENT_COMMON_FRAME_PARAM_H_
diff --git a/chromium/content/common/frame_param_macros.h b/chromium/content/common/frame_param_macros.h
deleted file mode 100644
index fd2256d7eec..00000000000
--- a/chromium/content/common/frame_param_macros.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 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.
-
-// Allows for sharing of IPC param structures between BrowserPlugin code and
-// RenderFrame code. All these should be folded directly back into the IPCs in
-// frame_messages.h once BrowserPlugin has been fully converted over to use
-// the RenderFrame infrastructure.
-//
-// TODO(ajwong): Remove once BrowserPlugin has been converted to use
-// RenderFrames. http://crbug.com/330264
-
-#ifndef CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-#define CONTENT_COMMON_FRAME_PARAM_MACROS_H_
-
-#include <stdint.h>
-
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "content/public/common/common_param_traits.h"
-#include "ipc/ipc_message_macros.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-IPC_STRUCT_BEGIN(FrameMsg_BuffersSwapped_Params)
- IPC_STRUCT_MEMBER(int, gpu_host_id)
- IPC_STRUCT_MEMBER(int, gpu_route_id)
- IPC_STRUCT_MEMBER(gpu::Mailbox, mailbox)
- IPC_STRUCT_MEMBER(gfx::Size, size)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(FrameMsg_CompositorFrameSwapped_Params)
- // Specifies which RenderWidget produced the CompositorFrame.
- IPC_STRUCT_MEMBER(int, producing_host_id)
- IPC_STRUCT_MEMBER(int, producing_route_id)
-
- IPC_STRUCT_MEMBER(cc::CompositorFrame, frame)
- IPC_STRUCT_MEMBER(uint32_t, output_surface_id)
- IPC_STRUCT_MEMBER(base::SharedMemoryHandle, shared_memory_handle)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(FrameHostMsg_CompositorFrameSwappedACK_Params)
- // Specifies which RenderWidget produced the CompositorFrame.
- IPC_STRUCT_MEMBER(int, producing_host_id)
- IPC_STRUCT_MEMBER(int, producing_route_id)
-
- IPC_STRUCT_MEMBER(uint32_t, output_surface_id)
- IPC_STRUCT_MEMBER(cc::CompositorFrameAck, ack)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(FrameHostMsg_ReclaimCompositorResources_Params)
- IPC_STRUCT_MEMBER(int, route_id)
- IPC_STRUCT_MEMBER(uint32_t, output_surface_id)
- IPC_STRUCT_MEMBER(int, renderer_host_id)
- IPC_STRUCT_MEMBER(cc::CompositorFrameAck, ack)
-IPC_STRUCT_END()
-
-#endif // CONTENT_COMMON_FRAME_PARAM_MACROS_H_
diff --git a/chromium/content/common/frame_replication_state.cc b/chromium/content/common/frame_replication_state.cc
index 0046466d7f1..00e835f5b92 100644
--- a/chromium/content/common/frame_replication_state.cc
+++ b/chromium/content/common/frame_replication_state.cc
@@ -11,19 +11,28 @@ namespace content {
FrameReplicationState::FrameReplicationState()
: sandbox_flags(blink::WebSandboxFlags::None),
scope(blink::WebTreeScopeType::Document),
- should_enforce_strict_mixed_content_checking(false) {}
+ should_enforce_strict_mixed_content_checking(false),
+ has_potentially_trustworthy_unique_origin(false) {}
FrameReplicationState::FrameReplicationState(
blink::WebTreeScopeType scope,
const std::string& name,
+ const std::string& unique_name,
blink::WebSandboxFlags sandbox_flags,
- bool should_enforce_strict_mixed_content_checking)
+ bool should_enforce_strict_mixed_content_checking,
+ bool has_potentially_trustworthy_unique_origin)
: origin(),
sandbox_flags(sandbox_flags),
name(name),
+ unique_name(unique_name),
scope(scope),
should_enforce_strict_mixed_content_checking(
- should_enforce_strict_mixed_content_checking) {}
+ should_enforce_strict_mixed_content_checking),
+ has_potentially_trustworthy_unique_origin(
+ has_potentially_trustworthy_unique_origin) {}
+
+FrameReplicationState::FrameReplicationState(
+ const FrameReplicationState& other) = default;
FrameReplicationState::~FrameReplicationState() {
}
diff --git a/chromium/content/common/frame_replication_state.h b/chromium/content/common/frame_replication_state.h
index 88978490e3f..f6373491a19 100644
--- a/chromium/content/common/frame_replication_state.h
+++ b/chromium/content/common/frame_replication_state.h
@@ -21,8 +21,11 @@ struct CONTENT_EXPORT FrameReplicationState {
FrameReplicationState();
FrameReplicationState(blink::WebTreeScopeType scope,
const std::string& name,
+ const std::string& unique_name,
blink::WebSandboxFlags sandbox_flags,
- bool should_enforce_strict_mixed_content_checking);
+ bool should_enforce_strict_mixed_content_checking,
+ bool has_potentially_trustworthy_unique_origin);
+ FrameReplicationState(const FrameReplicationState& other);
~FrameReplicationState();
// Current origin of the frame. This field is updated whenever a frame
@@ -37,20 +40,21 @@ struct CONTENT_EXPORT FrameReplicationState {
// compromized renderer.
url::Origin origin;
- // Current sandbox flags of the frame. |sandbox_flags| are initialized for
- // new child frames using the value of the <iframe> element's "sandbox"
- // attribute. They are updated dynamically whenever a parent frame updates an
- // <iframe>'s sandbox attribute via JavaScript.
+ // Sandbox flags currently in effect for the frame. |sandbox_flags| are
+ // initialized for new child frames using the value of the <iframe> element's
+ // "sandbox" attribute, combined with any sandbox flags in effect for the
+ // parent frame.
//
- // Updates to |sandbox_flags| are sent to proxies, but only after a
- // subsequent navigation of the (sandboxed) frame, since the flags only take
- // effect on navigation (see also FrameTreeNode::effective_sandbox_flags_).
- // The proxies need updated flags so that they can be inherited properly if a
- // proxy ever becomes a parent of a local frame.
+ // When a parent frame updates an <iframe>'s sandbox attribute via
+ // JavaScript, |sandbox_flags| are updated only after the child frame commits
+ // a navigation that makes the updated flags take effect. This is also the
+ // point at which updates are sent to proxies (see
+ // CommitPendingSandboxFlags()). The proxies need updated flags so that they
+ // can be inherited properly if a proxy ever becomes a parent of a local
+ // frame.
blink::WebSandboxFlags sandbox_flags;
- // The assigned name of the frame. This name can be empty, unlike the unique
- // name generated internally in the DOM tree.
+ // The assigned name of the frame (see WebFrame::assignedName()).
//
// |name| is set when a new child frame is created using the value of the
// <iframe> element's "name" attribute (see
@@ -62,6 +66,19 @@ struct CONTENT_EXPORT FrameReplicationState {
// frame using its updated name (e.g., using window.open(url, frame_name)).
std::string name;
+ // Unique name of the frame (see WebFrame::uniqueName()).
+ //
+ // |unique_name| is used in heuristics that try to identify the same frame
+ // across different, unrelated navigations (i.e. to refer to the frame
+ // when going back/forward in session history OR when refering to the frame
+ // in layout tests results).
+ //
+ // |unique_name| needs to be replicated to ensure that unique name for a given
+ // frame is the same across all renderers - without replication a renderer
+ // might arrive at a different value when recalculating the unique name from
+ // scratch.
+ std::string unique_name;
+
// Whether the frame is in a document tree or a shadow tree, per the Shadow
// DOM spec: https://w3c.github.io/webcomponents/spec/shadow/
// Note: This should really be const, as it can never change once a frame is
@@ -75,6 +92,10 @@ struct CONTENT_EXPORT FrameReplicationState {
// frames live in different processes.
bool should_enforce_strict_mixed_content_checking;
+ // True if a frame's origin is unique and should be considered potentially
+ // trustworthy.
+ bool has_potentially_trustworthy_unique_origin;
+
// TODO(alexmos): Eventually, this structure can also hold other state that
// needs to be replicated, such as frame sizing info.
};
diff --git a/chromium/content/common/gamepad_param_traits.cc b/chromium/content/common/gamepad_param_traits.cc
index 095154d8e4e..5a343fa1e06 100644
--- a/chromium/content/common/gamepad_param_traits.cc
+++ b/chromium/content/common/gamepad_param_traits.cc
@@ -33,13 +33,11 @@ void LogWebUCharString(
namespace IPC {
-void ParamTraits<WebGamepad>::Write(
- Message* m,
- const WebGamepad& p) {
+void ParamTraits<WebGamepad>::Write(base::Pickle* m, const WebGamepad& p) {
m->WriteData(reinterpret_cast<const char*>(&p), sizeof(WebGamepad));
}
-bool ParamTraits<WebGamepad>::Read(const Message* m,
+bool ParamTraits<WebGamepad>::Read(const base::Pickle* m,
base::PickleIterator* iter,
WebGamepad* p) {
int length;
diff --git a/chromium/content/common/gamepad_param_traits.h b/chromium/content/common/gamepad_param_traits.h
index 212c3063150..99576803b62 100644
--- a/chromium/content/common/gamepad_param_traits.h
+++ b/chromium/content/common/gamepad_param_traits.h
@@ -10,6 +10,7 @@
#include "ipc/ipc_param_traits.h"
namespace base {
+class Pickle;
class PickleIterator;
}
@@ -22,8 +23,8 @@ class Message;
template <>
struct ParamTraits<blink::WebGamepad> {
typedef blink::WebGamepad param_type;
- static void Write(Message* m, const blink::WebGamepad& p);
- static bool Read(const Message* m,
+ static void Write(base::Pickle* m, const blink::WebGamepad& p);
+ static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
blink::WebGamepad* p);
static void Log(const blink::WebGamepad& p, std::string* l);
diff --git a/chromium/content/common/geolocation_service.mojom b/chromium/content/common/geolocation_service.mojom
deleted file mode 100644
index a9c4e488646..00000000000
--- a/chromium/content/common/geolocation_service.mojom
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 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.
-
-module content;
-
-import "content/public/common/mojo_geoposition.mojom";
-
-// The Geolocation service provides updates on the device's location. By
-// default, it provides updates with low accuracy, but |SetHighAccuracy()| may
-// be called to change this.
-interface GeolocationService {
- SetHighAccuracy(bool high_accuracy);
-
- // Position is reported once it changes or immediately (to report the initial
- // position) if this is the first call to QueryNextPosition on this instance.
- // Position updates may be throttled by the service. Overlapping calls to
- // this method are prohibited and will be treated as a connection error.
- QueryNextPosition() => (MojoGeoposition geoposition);
-};
diff --git a/chromium/content/common/gpu/DEPS b/chromium/content/common/gpu/DEPS
index 2c01d5f2d7b..56ee2c3e9b8 100644
--- a/chromium/content/common/gpu/DEPS
+++ b/chromium/content/common/gpu/DEPS
@@ -2,9 +2,6 @@ include_rules = [
"+gpu/command_buffer",
"+libEGL",
"+libGLESv2",
- "+media/video/jpeg_decode_accelerator.h",
- "+media/video/video_decode_accelerator.h",
- "+media/video/video_encode_accelerator.h",
"+skia",
"+third_party/mesa",
]
diff --git a/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.h b/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.h
deleted file mode 100644
index f52000d6ddf..00000000000
--- a/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 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 CONTENT_COMMON_GPU_CA_LAYER_PARTIAL_DAMAGE_TREE_MAC_H_
-#define CONTENT_COMMON_GPU_CA_LAYER_PARTIAL_DAMAGE_TREE_MAC_H_
-
-#include <IOSurface/IOSurface.h>
-#include <QuartzCore/QuartzCore.h>
-#include <deque>
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace content {
-
-class CALayerPartialDamageTree {
- public:
- CALayerPartialDamageTree(bool allow_partial_swap,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::Rect& pixel_frame_rect);
- ~CALayerPartialDamageTree();
-
- base::ScopedCFTypeRef<IOSurfaceRef> RootLayerIOSurface();
- void CommitCALayers(CALayer* superlayer,
- scoped_ptr<CALayerPartialDamageTree> old_tree,
- float scale_factor,
- const gfx::Rect& pixel_damage_rect);
-
- private:
- class OverlayPlane;
-
- // This will populate |partial_damage_planes_|, potentially re-using the
- // CALayers and |partial_damage_planes_| from |old_tree|. After this function
- // completes, the back() of |partial_damage_planes_| is the plane that will
- // be updated this frame (and if it is empty, then the root plane will be
- // updated).
- void UpdatePartialDamagePlanes(CALayerPartialDamageTree* old_tree,
- const gfx::Rect& pixel_damage_rect);
-
- void UpdateRootAndPartialDamagePlanes(
- scoped_ptr<CALayerPartialDamageTree> old_tree,
- const gfx::Rect& pixel_damage_rect);
-
- void UpdateCALayers(CALayer* superlayer, float scale_factor);
-
- const bool allow_partial_swap_;
- scoped_ptr<OverlayPlane> root_plane_;
- std::deque<scoped_ptr<OverlayPlane>> partial_damage_planes_;
-};
-
-} // content
-
-#endif // CONTENT_COMMON_GPU_CA_LAYER_PARTIAL_DAMAGE_TREE_MAC_H_
diff --git a/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.mm b/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.mm
deleted file mode 100644
index f42738947a0..00000000000
--- a/chromium/content/common/gpu/ca_layer_partial_damage_tree_mac.mm
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2016 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 "content/common/gpu/ca_layer_partial_damage_tree_mac.h"
-
-#include "base/command_line.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/mac/sdk_forward_declarations.h"
-#include "base/trace_event/trace_event.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/transform.h"
-
-@interface CALayer(Private)
--(void)setContentsChanged;
-@end
-
-namespace content {
-namespace {
-
-// When selecting a CALayer to re-use for partial damage, this is the maximum
-// fraction of the merged layer's pixels that may be not-updated by the swap
-// before we consider the CALayer to not be a good enough match, and create a
-// new one.
-const float kMaximumPartialDamageWasteFraction = 1.2f;
-
-// The maximum number of partial damage layers that may be created before we
-// give up and remove them all (doing full damage in the process).
-const size_t kMaximumPartialDamageLayers = 8;
-
-} // namespace
-
-class CALayerPartialDamageTree::OverlayPlane {
- public:
- OverlayPlane(base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::Rect& pixel_frame_rect,
- const gfx::RectF& contents_rect)
- : io_surface(io_surface),
- contents_rect(contents_rect),
- pixel_frame_rect(pixel_frame_rect),
- layer_needs_update(true) {}
-
- ~OverlayPlane() {
- [ca_layer setContents:nil];
- [ca_layer removeFromSuperlayer];
- ca_layer.reset();
- }
-
- const base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
- const gfx::RectF contents_rect;
- const gfx::Rect pixel_frame_rect;
- bool layer_needs_update;
- base::scoped_nsobject<CALayer> ca_layer;
-
- void TakeCALayerFrom(OverlayPlane* other_plane) {
- ca_layer.swap(other_plane->ca_layer);
- }
-
- void UpdateProperties(float scale_factor) {
- if (layer_needs_update) {
- [ca_layer setOpaque:YES];
-
- id new_contents = static_cast<id>(io_surface.get());
- if ([ca_layer contents] == new_contents)
- [ca_layer setContentsChanged];
- else
- [ca_layer setContents:new_contents];
- [ca_layer setContentsRect:contents_rect.ToCGRect()];
-
- [ca_layer setAnchorPoint:CGPointZero];
-
- if ([ca_layer respondsToSelector:(@selector(setContentsScale:))])
- [ca_layer setContentsScale:scale_factor];
- gfx::RectF dip_frame_rect = gfx::RectF(pixel_frame_rect);
- dip_frame_rect.Scale(1 / scale_factor);
- [ca_layer setBounds:CGRectMake(0, 0, dip_frame_rect.width(),
- dip_frame_rect.height())];
- [ca_layer
- setPosition:CGPointMake(dip_frame_rect.x(), dip_frame_rect.y())];
- }
- static bool show_borders =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kShowMacOverlayBorders);
- if (show_borders) {
- base::ScopedCFTypeRef<CGColorRef> color;
- if (!layer_needs_update) {
- // Green represents contents that are unchanged across frames.
- color.reset(CGColorCreateGenericRGB(0, 1, 0, 1));
- } else {
- // Red represents damaged contents.
- color.reset(CGColorCreateGenericRGB(1, 0, 0, 1));
- }
- [ca_layer setBorderWidth:1];
- [ca_layer setBorderColor:color];
- }
- layer_needs_update = false;
- }
-
- private:
-};
-
-void CALayerPartialDamageTree::UpdatePartialDamagePlanes(
- CALayerPartialDamageTree* old_tree,
- const gfx::Rect& pixel_damage_rect) {
- // Don't create partial damage layers if partial swap is disabled.
- if (!allow_partial_swap_)
- return;
- // Only create partial damage layers when building on top of an existing tree.
- if (!old_tree)
- return;
- // If the frame size has changed, discard all of the old partial damage
- // layers.
- if (old_tree->root_plane_->pixel_frame_rect != root_plane_->pixel_frame_rect)
- return;
- // If there is full damage, discard all of the old partial damage layers.
- if (pixel_damage_rect == root_plane_->pixel_frame_rect)
- return;
-
- // If there is no damage, don't change anything.
- if (pixel_damage_rect.IsEmpty()) {
- std::swap(partial_damage_planes_, old_tree->partial_damage_planes_);
- return;
- }
-
- // Find the last partial damage plane to re-use the CALayer from. Grow the
- // new rect for this layer to include this damage, and all nearby partial
- // damage layers.
- scoped_ptr<OverlayPlane> plane_for_swap;
- {
- auto plane_to_reuse_iter = old_tree->partial_damage_planes_.end();
- gfx::Rect plane_to_reuse_enlarged_pixel_damage_rect;
-
- for (auto old_plane_iter = old_tree->partial_damage_planes_.begin();
- old_plane_iter != old_tree->partial_damage_planes_.end();
- ++old_plane_iter) {
- gfx::Rect enlarged_pixel_damage_rect =
- (*old_plane_iter)->pixel_frame_rect;
- enlarged_pixel_damage_rect.Union(pixel_damage_rect);
-
- // Compute the fraction of the pixels that would not be updated by this
- // swap. If it is too big, try another layer.
- float waste_fraction = enlarged_pixel_damage_rect.size().GetArea() * 1.f /
- pixel_damage_rect.size().GetArea();
- if (waste_fraction > kMaximumPartialDamageWasteFraction)
- continue;
-
- plane_to_reuse_iter = old_plane_iter;
- plane_to_reuse_enlarged_pixel_damage_rect.Union(
- enlarged_pixel_damage_rect);
- }
- if (plane_to_reuse_iter != old_tree->partial_damage_planes_.end()) {
- gfx::RectF enlarged_contents_rect =
- gfx::RectF(plane_to_reuse_enlarged_pixel_damage_rect);
- enlarged_contents_rect.Scale(1. / root_plane_->pixel_frame_rect.width(),
- 1. / root_plane_->pixel_frame_rect.height());
-
- plane_for_swap.reset(new OverlayPlane(
- root_plane_->io_surface, plane_to_reuse_enlarged_pixel_damage_rect,
- enlarged_contents_rect));
-
- plane_for_swap->TakeCALayerFrom((*plane_to_reuse_iter).get());
- if (*plane_to_reuse_iter != old_tree->partial_damage_planes_.back()) {
- CALayer* superlayer = [plane_for_swap->ca_layer superlayer];
- [plane_for_swap->ca_layer removeFromSuperlayer];
- [superlayer addSublayer:plane_for_swap->ca_layer];
- }
- }
- }
-
- // If we haven't found an appropriate layer to re-use, create a new one, if
- // we haven't already created too many.
- if (!plane_for_swap.get() &&
- old_tree->partial_damage_planes_.size() < kMaximumPartialDamageLayers) {
- gfx::RectF contents_rect = gfx::RectF(pixel_damage_rect);
- contents_rect.Scale(1. / root_plane_->pixel_frame_rect.width(),
- 1. / root_plane_->pixel_frame_rect.height());
- plane_for_swap.reset(new OverlayPlane(root_plane_->io_surface,
- pixel_damage_rect, contents_rect));
- }
-
- // And if we still don't have a layer, do full damage.
- if (!plane_for_swap.get())
- return;
-
- // Walk all old partial damage planes. Remove anything that is now completely
- // covered, and move everything else into the new |partial_damage_planes_|.
- for (auto& old_plane : old_tree->partial_damage_planes_) {
- if (!old_plane.get())
- continue;
- // Intersect the planes' frames with the new root plane to ensure that
- // they don't get kept alive inappropriately.
- gfx::Rect old_plane_frame_rect = old_plane->pixel_frame_rect;
- old_plane_frame_rect.Intersect(root_plane_->pixel_frame_rect);
-
- bool old_plane_covered_by_swap = false;
- if (plane_for_swap.get() &&
- plane_for_swap->pixel_frame_rect.Contains(old_plane_frame_rect)) {
- old_plane_covered_by_swap = true;
- }
- if (!old_plane_covered_by_swap) {
- DCHECK(old_plane->ca_layer);
- partial_damage_planes_.push_back(std::move(old_plane));
- }
- }
-
- partial_damage_planes_.push_back(std::move(plane_for_swap));
-}
-
-void CALayerPartialDamageTree::UpdateRootAndPartialDamagePlanes(
- scoped_ptr<CALayerPartialDamageTree> old_tree,
- const gfx::Rect& pixel_damage_rect) {
- // First update the partial damage tree.
- UpdatePartialDamagePlanes(old_tree.get(), pixel_damage_rect);
- if (old_tree) {
- if (partial_damage_planes_.empty()) {
- // If there are no partial damage planes, then we will be updating the
- // root layer. Take the CALayer from the old tree.
- root_plane_->TakeCALayerFrom(old_tree->root_plane_.get());
- } else {
- // If there is a partial damage tree, then just take the old plane
- // from the previous frame, so that there is no update to it.
- root_plane_.swap(old_tree->root_plane_);
- }
- }
-}
-
-void CALayerPartialDamageTree::UpdateCALayers(CALayer* superlayer,
- float scale_factor) {
- if (!allow_partial_swap_) {
- DCHECK(partial_damage_planes_.empty());
- return;
- }
-
- // Allocate and update CALayers for the backbuffer and partial damage layers.
- if (!root_plane_->ca_layer) {
- DCHECK(partial_damage_planes_.empty());
- root_plane_->ca_layer.reset([[CALayer alloc] init]);
- [superlayer setSublayers:nil];
- [superlayer addSublayer:root_plane_->ca_layer];
- }
- // Excessive logging to debug white screens (crbug.com/583805).
- // TODO(ccameron): change this back to a DLOG.
- if ([root_plane_->ca_layer superlayer] != superlayer) {
- LOG(ERROR) << "CALayerPartialDamageTree root layer not attached to tree.";
- }
- for (auto& plane : partial_damage_planes_) {
- if (!plane->ca_layer) {
- DCHECK(plane == partial_damage_planes_.back());
- plane->ca_layer.reset([[CALayer alloc] init]);
- }
- if (![plane->ca_layer superlayer]) {
- DCHECK(plane == partial_damage_planes_.back());
- [superlayer addSublayer:plane->ca_layer];
- }
- }
- root_plane_->UpdateProperties(scale_factor);
- for (auto& plane : partial_damage_planes_)
- plane->UpdateProperties(scale_factor);
-}
-
-CALayerPartialDamageTree::CALayerPartialDamageTree(
- bool allow_partial_swap,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::Rect& pixel_frame_rect)
- : allow_partial_swap_(allow_partial_swap) {
- root_plane_.reset(
- new OverlayPlane(io_surface, pixel_frame_rect, gfx::RectF(0, 0, 1, 1)));
-}
-
-CALayerPartialDamageTree::~CALayerPartialDamageTree() {}
-
-base::ScopedCFTypeRef<IOSurfaceRef>
-CALayerPartialDamageTree::RootLayerIOSurface() {
- return root_plane_->io_surface;
-}
-
-void CALayerPartialDamageTree::CommitCALayers(
- CALayer* superlayer,
- scoped_ptr<CALayerPartialDamageTree> old_tree,
- float scale_factor,
- const gfx::Rect& pixel_damage_rect) {
- TRACE_EVENT0("gpu", "CALayerPartialDamageTree::CommitCALayers");
- UpdateRootAndPartialDamagePlanes(std::move(old_tree), pixel_damage_rect);
- UpdateCALayers(superlayer, scale_factor);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/ca_layer_tree_mac.h b/chromium/content/common/gpu/ca_layer_tree_mac.h
deleted file mode 100644
index d20bdb0d8be..00000000000
--- a/chromium/content/common/gpu/ca_layer_tree_mac.h
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2016 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 CONTENT_COMMON_GPU_CA_LAYER_TREE_MAC_H_
-#define CONTENT_COMMON_GPU_CA_LAYER_TREE_MAC_H_
-
-#include <IOSurface/IOSurface.h>
-#include <QuartzCore/QuartzCore.h>
-#include <deque>
-#include <vector>
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/transform.h"
-
-namespace content {
-
-// The CALayerTree will construct a hierarchy of CALayers from a linear list,
-// using the algorithm and structure referenced described in
-// https://docs.google.com/document/d/1DtSN9zzvCF44_FQPM7ie01UxGHagQ66zfF5L9HnigQY/edit?usp=sharing
-class CALayerTree {
- public:
- CALayerTree();
-
- // This will remove all CALayers from this tree from their superlayer.
- ~CALayerTree();
-
- // Append the description of a new CALayer to the tree. This will not
- // create any new CALayers until CommitScheduledCALayers is called. This
- // cannot be called anymore after CommitScheduledCALayers has been called.
- bool ScheduleCALayer(bool is_clipped,
- const gfx::Rect& clip_rect,
- unsigned sorting_context_id,
- const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity);
-
- // Create a CALayer tree for the scheduled layers, and set |superlayer| to
- // have only this tree as its sublayers. If |old_tree| is non-null, then try
- // to re-use the CALayers of |old_tree| as much as possible. |old_tree| will
- // be destroyed at the end of the function, and any CALayers in it which were
- // not re-used by |this| will be removed from the CALayer hierarchy.
- void CommitScheduledCALayers(CALayer* superlayer,
- scoped_ptr<CALayerTree> old_tree,
- float scale_factor);
-
- private:
- struct RootLayer;
- struct ClipAndSortingLayer;
- struct TransformLayer;
- struct ContentLayer;
-
- struct RootLayer {
- RootLayer();
-
- // This will remove |ca_layer| from its superlayer, if |ca_layer| is
- // non-nil.
- ~RootLayer();
-
- // Append a new content layer, without modifying the actual CALayer
- // structure.
- bool AddContentLayer(bool is_clipped,
- const gfx::Rect& clip_rect,
- unsigned sorting_context_id,
- const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity);
-
- // Allocate CALayers for this layer and its children, and set their
- // properties appropriately. Re-use the CALayers from |old_layer| if
- // possible. If re-using a CALayer from |old_layer|, reset its |ca_layer|
- // to nil, so that its destructor will not remove an active CALayer.
- void CommitToCA(CALayer* superlayer,
- RootLayer* old_layer,
- float scale_factor);
-
- std::vector<ClipAndSortingLayer> clip_and_sorting_layers;
- base::scoped_nsobject<CALayer> ca_layer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RootLayer);
- };
- struct ClipAndSortingLayer {
- ClipAndSortingLayer(bool is_clipped,
- gfx::Rect clip_rect,
- unsigned sorting_context_id,
- bool is_singleton_sorting_context);
- ClipAndSortingLayer(ClipAndSortingLayer&& layer);
-
- // See the behavior of RootLayer for the effects of these functions on the
- // |ca_layer| member and |old_layer| argument.
- ~ClipAndSortingLayer();
- void AddContentLayer(const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity);
- void CommitToCA(CALayer* superlayer,
- ClipAndSortingLayer* old_layer,
- float scale_factor);
-
- std::vector<TransformLayer> transform_layers;
- bool is_clipped = false;
- gfx::Rect clip_rect;
- unsigned sorting_context_id = 0;
- bool is_singleton_sorting_context = false;
- base::scoped_nsobject<CALayer> ca_layer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ClipAndSortingLayer);
- };
- struct TransformLayer {
- TransformLayer(const gfx::Transform& transform);
- TransformLayer(TransformLayer&& layer);
-
- // See the behavior of RootLayer for the effects of these functions on the
- // |ca_layer| member and |old_layer| argument.
- ~TransformLayer();
- void AddContentLayer(base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity);
- void CommitToCA(CALayer* superlayer,
- TransformLayer* old_layer,
- float scale_factor);
-
- gfx::Transform transform;
- std::vector<ContentLayer> content_layers;
- base::scoped_nsobject<CALayer> ca_layer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TransformLayer);
- };
- struct ContentLayer {
- ContentLayer(base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity);
- ContentLayer(ContentLayer&& layer);
-
- // See the behavior of RootLayer for the effects of these functions on the
- // |ca_layer| member and |old_layer| argument.
- ~ContentLayer();
- void CommitToCA(CALayer* parent,
- ContentLayer* old_layer,
- float scale_factor);
-
- const base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
- gfx::RectF contents_rect;
- gfx::Rect rect;
- unsigned background_color = 0;
- // Note that the CoreAnimation edge antialiasing mask is not the same as
- // the edge antialiasing mask passed to the constructor.
- CAEdgeAntialiasingMask ca_edge_aa_mask = 0;
- float opacity = 1;
- base::scoped_nsobject<CALayer> ca_layer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ContentLayer);
- };
-
- RootLayer root_layer_;
- float scale_factor_ = 1;
- bool has_committed_ = false;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CALayerTree);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CA_LAYER_TREE_MAC_H_
diff --git a/chromium/content/common/gpu/ca_layer_tree_mac.mm b/chromium/content/common/gpu/ca_layer_tree_mac.mm
deleted file mode 100644
index 8c7d93886a5..00000000000
--- a/chromium/content/common/gpu/ca_layer_tree_mac.mm
+++ /dev/null
@@ -1,455 +0,0 @@
-// Copyright 2016 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 "content/common/gpu/ca_layer_tree_mac.h"
-
-#include "base/command_line.h"
-#include "base/mac/sdk_forward_declarations.h"
-#include "base/trace_event/trace_event.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/cocoa/animation_utils.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/geometry/dip_util.h"
-
-namespace content {
-
-CALayerTree::CALayerTree() {}
-CALayerTree::~CALayerTree() {}
-
-bool CALayerTree::ScheduleCALayer(
- bool is_clipped,
- const gfx::Rect& clip_rect,
- unsigned sorting_context_id,
- const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity) {
- // Excessive logging to debug white screens (crbug.com/583805).
- // TODO(ccameron): change this back to a DLOG.
- if (has_committed_) {
- LOG(ERROR) << "ScheduleCALayer called after CommitScheduledCALayers.";
- return false;
- }
- return root_layer_.AddContentLayer(is_clipped, clip_rect, sorting_context_id,
- transform, io_surface, contents_rect, rect,
- background_color, edge_aa_mask, opacity);
-}
-
-void CALayerTree::CommitScheduledCALayers(CALayer* superlayer,
- scoped_ptr<CALayerTree> old_tree,
- float scale_factor) {
- TRACE_EVENT0("gpu", "CALayerTree::CommitScheduledCALayers");
- RootLayer* old_root_layer = nullptr;
- if (old_tree) {
- DCHECK(old_tree->has_committed_);
- if (old_tree->scale_factor_ == scale_factor)
- old_root_layer = &old_tree->root_layer_;
- }
-
- root_layer_.CommitToCA(superlayer, old_root_layer, scale_factor);
- // If there are any extra CALayers in |old_tree| that were not stolen by this
- // tree, they will be removed from the CALayer tree in this deallocation.
- old_tree.reset();
- has_committed_ = true;
- scale_factor_ = scale_factor;
-}
-
-CALayerTree::RootLayer::RootLayer() {}
-
-// Note that for all destructors, the the CALayer will have been reset to nil if
-// another layer has taken it.
-CALayerTree::RootLayer::~RootLayer() {
- [ca_layer removeFromSuperlayer];
-}
-
-CALayerTree::ClipAndSortingLayer::ClipAndSortingLayer(
- bool is_clipped,
- gfx::Rect clip_rect,
- unsigned sorting_context_id,
- bool is_singleton_sorting_context)
- : is_clipped(is_clipped),
- clip_rect(clip_rect),
- sorting_context_id(sorting_context_id),
- is_singleton_sorting_context(is_singleton_sorting_context) {}
-
-CALayerTree::ClipAndSortingLayer::ClipAndSortingLayer(
- ClipAndSortingLayer&& layer)
- : transform_layers(std::move(layer.transform_layers)),
- is_clipped(layer.is_clipped),
- clip_rect(layer.clip_rect),
- sorting_context_id(layer.sorting_context_id),
- is_singleton_sorting_context(
- layer.is_singleton_sorting_context),
- ca_layer(layer.ca_layer) {
- // Ensure that the ca_layer be reset, so that when the destructor is called,
- // the layer hierarchy is unaffected.
- // TODO(ccameron): Add a move constructor for scoped_nsobject to do this
- // automatically.
- layer.ca_layer.reset();
-}
-
-CALayerTree::ClipAndSortingLayer::~ClipAndSortingLayer() {
- [ca_layer removeFromSuperlayer];
-}
-
-CALayerTree::TransformLayer::TransformLayer(const gfx::Transform& transform)
- : transform(transform) {}
-
-CALayerTree::TransformLayer::TransformLayer(TransformLayer&& layer)
- : transform(layer.transform),
- content_layers(std::move(layer.content_layers)),
- ca_layer(layer.ca_layer) {
- layer.ca_layer.reset();
-}
-
-CALayerTree::TransformLayer::~TransformLayer() {
- [ca_layer removeFromSuperlayer];
-}
-
-CALayerTree::ContentLayer::ContentLayer(
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity)
- : io_surface(io_surface),
- contents_rect(contents_rect),
- rect(rect),
- background_color(background_color),
- ca_edge_aa_mask(0),
- opacity(opacity) {
- // Because the root layer has setGeometryFlipped:YES, there is some ambiguity
- // about what exactly top and bottom mean. This ambiguity is resolved in
- // different ways for solid color CALayers and for CALayers that have content
- // (surprise!). For CALayers with IOSurface content, the top edge in the AA
- // mask refers to what appears as the bottom edge on-screen. For CALayers
- // without content (solid color layers), the top edge in the AA mask is the
- // top edge on-screen.
- // http://crbug.com/567946
- if (edge_aa_mask & GL_CA_LAYER_EDGE_LEFT_CHROMIUM)
- ca_edge_aa_mask |= kCALayerLeftEdge;
- if (edge_aa_mask & GL_CA_LAYER_EDGE_RIGHT_CHROMIUM)
- ca_edge_aa_mask |= kCALayerRightEdge;
- if (io_surface) {
- if (edge_aa_mask & GL_CA_LAYER_EDGE_TOP_CHROMIUM)
- ca_edge_aa_mask |= kCALayerBottomEdge;
- if (edge_aa_mask & GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM)
- ca_edge_aa_mask |= kCALayerTopEdge;
- } else {
- if (edge_aa_mask & GL_CA_LAYER_EDGE_TOP_CHROMIUM)
- ca_edge_aa_mask |= kCALayerTopEdge;
- if (edge_aa_mask & GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM)
- ca_edge_aa_mask |= kCALayerBottomEdge;
- }
-
- // Ensure that the IOSurface be in use as soon as it is added to a
- // ContentLayer, so that, by the time that the call to SwapBuffers completes,
- // all IOSurfaces that can be used as CALayer contents in the future will be
- // marked as InUse.
- if (io_surface)
- IOSurfaceIncrementUseCount(io_surface);
-}
-
-CALayerTree::ContentLayer::ContentLayer(ContentLayer&& layer)
- : io_surface(layer.io_surface),
- contents_rect(layer.contents_rect),
- rect(layer.rect),
- background_color(layer.background_color),
- ca_edge_aa_mask(layer.ca_edge_aa_mask),
- opacity(layer.opacity),
- ca_layer(layer.ca_layer) {
- DCHECK(!layer.ca_layer);
- layer.ca_layer.reset();
- // See remarks in the non-move constructor.
- if (io_surface)
- IOSurfaceIncrementUseCount(io_surface);
-}
-
-CALayerTree::ContentLayer::~ContentLayer() {
- [ca_layer removeFromSuperlayer];
- // By the time the destructor is called, the IOSurface will have been passed
- // to the WindowServer, and will remain InUse by the WindowServer as long as
- // is needed to avoid recycling bugs.
- if (io_surface)
- IOSurfaceDecrementUseCount(io_surface);
-}
-
-bool CALayerTree::RootLayer::AddContentLayer(
- bool is_clipped,
- const gfx::Rect& clip_rect,
- unsigned sorting_context_id,
- const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity) {
- bool needs_new_clip_and_sorting_layer = true;
-
- // In sorting_context_id 0, all quads are listed in back-to-front order.
- // This is accomplished by having the CALayers be siblings of each other.
- // If a quad has a 3D transform, it is necessary to put it in its own sorting
- // context, so that it will not intersect with quads before and after it.
- bool is_singleton_sorting_context =
- !sorting_context_id && !transform.IsFlat();
-
- if (!clip_and_sorting_layers.empty()) {
- ClipAndSortingLayer& current_layer = clip_and_sorting_layers.back();
- // It is in error to change the clipping settings within a non-zero sorting
- // context. The result will be incorrect layering and intersection.
- if (sorting_context_id &&
- current_layer.sorting_context_id == sorting_context_id &&
- (current_layer.is_clipped != is_clipped ||
- current_layer.clip_rect != clip_rect)) {
- // Excessive logging to debug white screens (crbug.com/583805).
- // TODO(ccameron): change this back to a DLOG.
- LOG(ERROR) << "CALayer changed clip inside non-zero sorting context.";
- return false;
- }
- if (!is_singleton_sorting_context &&
- !current_layer.is_singleton_sorting_context &&
- current_layer.is_clipped == is_clipped &&
- current_layer.clip_rect == clip_rect &&
- current_layer.sorting_context_id == sorting_context_id) {
- needs_new_clip_and_sorting_layer = false;
- }
- }
- if (needs_new_clip_and_sorting_layer) {
- clip_and_sorting_layers.push_back(
- ClipAndSortingLayer(is_clipped, clip_rect, sorting_context_id,
- is_singleton_sorting_context));
- }
- clip_and_sorting_layers.back().AddContentLayer(
- transform, io_surface, contents_rect, rect, background_color,
- edge_aa_mask, opacity);
- return true;
-}
-
-void CALayerTree::ClipAndSortingLayer::AddContentLayer(
- const gfx::Transform& transform,
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity) {
- bool needs_new_transform_layer = true;
- if (!transform_layers.empty()) {
- const TransformLayer& current_layer = transform_layers.back();
- if (current_layer.transform == transform)
- needs_new_transform_layer = false;
- }
- if (needs_new_transform_layer)
- transform_layers.push_back(TransformLayer(transform));
- transform_layers.back().AddContentLayer(
- io_surface, contents_rect, rect, background_color, edge_aa_mask, opacity);
-}
-
-void CALayerTree::TransformLayer::AddContentLayer(
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
- const gfx::RectF& contents_rect,
- const gfx::Rect& rect,
- unsigned background_color,
- unsigned edge_aa_mask,
- float opacity) {
- content_layers.push_back(ContentLayer(io_surface, contents_rect, rect,
- background_color, edge_aa_mask,
- opacity));
-}
-
-void CALayerTree::RootLayer::CommitToCA(CALayer* superlayer,
- RootLayer* old_layer,
- float scale_factor) {
- if (old_layer) {
- DCHECK(old_layer->ca_layer);
- std::swap(ca_layer, old_layer->ca_layer);
- } else {
- ca_layer.reset([[CALayer alloc] init]);
- [ca_layer setAnchorPoint:CGPointZero];
- [superlayer setSublayers:nil];
- [superlayer addSublayer:ca_layer];
- [superlayer setBorderWidth:0];
- }
- // Excessive logging to debug white screens (crbug.com/583805).
- // TODO(ccameron): change this back to a DCHECK.
- if ([ca_layer superlayer] != superlayer) {
- LOG(ERROR) << "CALayerTree root layer not attached to tree.";
- }
-
- for (size_t i = 0; i < clip_and_sorting_layers.size(); ++i) {
- ClipAndSortingLayer* old_clip_and_sorting_layer = nullptr;
- if (old_layer && i < old_layer->clip_and_sorting_layers.size()) {
- old_clip_and_sorting_layer = &old_layer->clip_and_sorting_layers[i];
- }
- clip_and_sorting_layers[i].CommitToCA(
- ca_layer.get(), old_clip_and_sorting_layer, scale_factor);
- }
-}
-
-void CALayerTree::ClipAndSortingLayer::CommitToCA(
- CALayer* superlayer,
- ClipAndSortingLayer* old_layer,
- float scale_factor) {
- bool update_is_clipped = true;
- bool update_clip_rect = true;
- if (old_layer) {
- DCHECK(old_layer->ca_layer);
- std::swap(ca_layer, old_layer->ca_layer);
- update_is_clipped = old_layer->is_clipped != is_clipped;
- update_clip_rect = old_layer->clip_rect != clip_rect;
- } else {
- ca_layer.reset([[CALayer alloc] init]);
- [ca_layer setAnchorPoint:CGPointZero];
- [superlayer addSublayer:ca_layer];
- }
- // Excessive logging to debug white screens (crbug.com/583805).
- // TODO(ccameron): change this back to a DCHECK.
- if ([ca_layer superlayer] != superlayer) {
- LOG(ERROR) << "CALayerTree root layer not attached to tree.";
- }
-
- if (update_is_clipped)
- [ca_layer setMasksToBounds:is_clipped];
-
- if (update_clip_rect) {
- if (is_clipped) {
- gfx::RectF dip_clip_rect = gfx::RectF(clip_rect);
- dip_clip_rect.Scale(1 / scale_factor);
- [ca_layer setPosition:CGPointMake(dip_clip_rect.x(), dip_clip_rect.y())];
- [ca_layer setBounds:CGRectMake(0, 0, dip_clip_rect.width(),
- dip_clip_rect.height())];
- [ca_layer
- setSublayerTransform:CATransform3DMakeTranslation(
- -dip_clip_rect.x(), -dip_clip_rect.y(), 0)];
- } else {
- [ca_layer setPosition:CGPointZero];
- [ca_layer setBounds:CGRectZero];
- [ca_layer setSublayerTransform:CATransform3DIdentity];
- }
- }
-
- for (size_t i = 0; i < transform_layers.size(); ++i) {
- TransformLayer* old_transform_layer = nullptr;
- if (old_layer && i < old_layer->transform_layers.size())
- old_transform_layer = &old_layer->transform_layers[i];
- transform_layers[i].CommitToCA(ca_layer.get(), old_transform_layer,
- scale_factor);
- }
-}
-
-void CALayerTree::TransformLayer::CommitToCA(CALayer* superlayer,
- TransformLayer* old_layer,
- float scale_factor) {
- bool update_transform = true;
- if (old_layer) {
- DCHECK(old_layer->ca_layer);
- std::swap(ca_layer, old_layer->ca_layer);
- update_transform = old_layer->transform != transform;
- } else {
- ca_layer.reset([[CATransformLayer alloc] init]);
- [superlayer addSublayer:ca_layer];
- }
- DCHECK_EQ([ca_layer superlayer], superlayer);
-
- if (update_transform) {
- gfx::Transform pre_scale;
- gfx::Transform post_scale;
- pre_scale.Scale(1 / scale_factor, 1 / scale_factor);
- post_scale.Scale(scale_factor, scale_factor);
- gfx::Transform conjugated_transform = pre_scale * transform * post_scale;
-
- CATransform3D ca_transform;
- conjugated_transform.matrix().asColMajord(&ca_transform.m11);
- [ca_layer setTransform:ca_transform];
- }
-
- for (size_t i = 0; i < content_layers.size(); ++i) {
- ContentLayer* old_content_layer = nullptr;
- if (old_layer && i < old_layer->content_layers.size())
- old_content_layer = &old_layer->content_layers[i];
- content_layers[i].CommitToCA(ca_layer.get(), old_content_layer,
- scale_factor);
- }
-}
-
-void CALayerTree::ContentLayer::CommitToCA(CALayer* superlayer,
- ContentLayer* old_layer,
- float scale_factor) {
- bool update_contents = true;
- bool update_contents_rect = true;
- bool update_rect = true;
- bool update_background_color = true;
- bool update_ca_edge_aa_mask = true;
- bool update_opacity = true;
- if (old_layer) {
- DCHECK(old_layer->ca_layer);
- std::swap(ca_layer, old_layer->ca_layer);
- update_contents = old_layer->io_surface != io_surface;
- update_contents_rect = old_layer->contents_rect != contents_rect;
- update_rect = old_layer->rect != rect;
- update_background_color = old_layer->background_color != background_color;
- update_ca_edge_aa_mask = old_layer->ca_edge_aa_mask != ca_edge_aa_mask;
- update_opacity = old_layer->opacity != opacity;
- } else {
- ca_layer.reset([[CALayer alloc] init]);
- [ca_layer setAnchorPoint:CGPointZero];
- [superlayer addSublayer:ca_layer];
- }
- DCHECK_EQ([ca_layer superlayer], superlayer);
- bool update_anything = update_contents || update_contents_rect ||
- update_rect || update_background_color ||
- update_ca_edge_aa_mask || update_opacity;
-
- if (update_contents) {
- [ca_layer setContents:static_cast<id>(io_surface.get())];
- if ([ca_layer respondsToSelector:(@selector(setContentsScale:))])
- [ca_layer setContentsScale:scale_factor];
- }
- if (update_contents_rect)
- [ca_layer setContentsRect:contents_rect.ToCGRect()];
- if (update_rect) {
- gfx::RectF dip_rect = gfx::RectF(rect);
- dip_rect.Scale(1 / scale_factor);
- [ca_layer setPosition:CGPointMake(dip_rect.x(), dip_rect.y())];
- [ca_layer setBounds:CGRectMake(0, 0, dip_rect.width(), dip_rect.height())];
- }
- if (update_background_color) {
- CGFloat rgba_color_components[4] = {
- SkColorGetR(background_color) / 255.,
- SkColorGetG(background_color) / 255.,
- SkColorGetB(background_color) / 255.,
- SkColorGetA(background_color) / 255.,
- };
- base::ScopedCFTypeRef<CGColorRef> srgb_background_color(CGColorCreate(
- CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components));
- [ca_layer setBackgroundColor:srgb_background_color];
- }
- if (update_ca_edge_aa_mask)
- [ca_layer setEdgeAntialiasingMask:ca_edge_aa_mask];
- if (update_opacity)
- [ca_layer setOpacity:opacity];
-
- static bool show_borders = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kShowMacOverlayBorders);
- if (show_borders) {
- base::ScopedCFTypeRef<CGColorRef> color;
- if (update_anything) {
- // Pink represents a CALayer that changed this frame.
- color.reset(CGColorCreateGenericRGB(1, 0, 1, 1));
- } else {
- // Grey represents a CALayer that has not changed.
- color.reset(CGColorCreateGenericRGB(0, 0, 0, 0.1));
- }
- [ca_layer setBorderWidth:1];
- [ca_layer setBorderColor:color];
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/child_window_surface_win.cc b/chromium/content/common/gpu/child_window_surface_win.cc
deleted file mode 100644
index 738caea87ad..00000000000
--- a/chromium/content/common/gpu/child_window_surface_win.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/child_window_surface_win.h"
-
-#include "base/compiler_specific.h"
-#include "base/win/scoped_hdc.h"
-#include "base/win/wrapped_window_proc.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ui/base/win/hidden_window.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/win/hwnd_util.h"
-#include "ui/gl/egl_util.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface_egl.h"
-#include "ui/gl/scoped_make_current.h"
-
-namespace content {
-
-namespace {
-
-ATOM g_window_class;
-
-LRESULT CALLBACK IntermediateWindowProc(HWND window,
- UINT message,
- WPARAM w_param,
- LPARAM l_param) {
- switch (message) {
- case WM_ERASEBKGND:
- // Prevent windows from erasing the background.
- return 1;
- case WM_PAINT:
- PAINTSTRUCT paint;
- if (BeginPaint(window, &paint)) {
- ChildWindowSurfaceWin* window_surface =
- reinterpret_cast<ChildWindowSurfaceWin*>(
- gfx::GetWindowUserData(window));
- DCHECK(window_surface);
-
- // Wait to clear the contents until a GL draw occurs, as otherwise an
- // unsightly black flash may happen if the GL contents are still
- // transparent.
- window_surface->InvalidateWindowRect(gfx::Rect(paint.rcPaint));
- EndPaint(window, &paint);
- }
- return 0;
- default:
- return DefWindowProc(window, message, w_param, l_param);
- }
-}
-
-void InitializeWindowClass() {
- if (g_window_class)
- return;
-
- WNDCLASSEX intermediate_class;
- base::win::InitializeWindowClass(
- L"Intermediate D3D Window",
- &base::win::WrappedWindowProc<IntermediateWindowProc>, CS_OWNDC, 0, 0,
- nullptr, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), nullptr,
- nullptr, nullptr, &intermediate_class);
- g_window_class = RegisterClassEx(&intermediate_class);
- if (!g_window_class) {
- LOG(ERROR) << "RegisterClass failed.";
- return;
- }
-}
-}
-
-ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager,
- HWND parent_window)
- : gfx::NativeViewGLSurfaceEGL(0),
- parent_window_(parent_window),
- manager_(manager) {
- // Don't use EGL_ANGLE_window_fixed_size so that we can avoid recreating the
- // window surface, which can cause flicker on DirectComposition.
- enable_fixed_size_angle_ = false;
-}
-
-EGLConfig ChildWindowSurfaceWin::GetConfig() {
- if (!config_) {
- int alpha_size = alpha_ ? 8 : EGL_DONT_CARE;
-
- EGLint config_attribs[] = {EGL_ALPHA_SIZE,
- alpha_size,
- EGL_BLUE_SIZE,
- 8,
- EGL_GREEN_SIZE,
- 8,
- EGL_RED_SIZE,
- 8,
- EGL_RENDERABLE_TYPE,
- EGL_OPENGL_ES2_BIT,
- EGL_SURFACE_TYPE,
- EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- EGL_NONE};
-
- EGLDisplay display = GetHardwareDisplay();
- EGLint num_configs;
- if (!eglChooseConfig(display, config_attribs, &config_, 1, &num_configs)) {
- LOG(ERROR) << "eglChooseConfig failed with error "
- << ui::GetLastEGLErrorString();
- return NULL;
- }
- }
-
- return config_;
-}
-
-bool ChildWindowSurfaceWin::InitializeNativeWindow() {
- if (window_)
- return true;
- InitializeWindowClass();
- DCHECK(g_window_class);
-
- RECT windowRect;
- GetClientRect(parent_window_, &windowRect);
-
- window_ = CreateWindowEx(
- WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"",
- WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0,
- windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
- ui::GetHiddenWindow(), NULL, NULL, NULL);
- gfx::SetWindowUserData(window_, this);
- manager_->Send(new GpuHostMsg_AcceleratedSurfaceCreatedChildWindow(
- parent_window_, window_));
- return true;
-}
-
-bool ChildWindowSurfaceWin::Resize(const gfx::Size& size,
- float scale_factor,
- bool has_alpha) {
- if (!SupportsPostSubBuffer()) {
- if (!MoveWindow(window_, 0, 0, size.width(), size.height(), FALSE)) {
- return false;
- }
- return gfx::NativeViewGLSurfaceEGL::Resize(size, scale_factor, has_alpha);
- } else {
- if (size == GetSize() && has_alpha == alpha_)
- return true;
-
- if (!MoveWindow(window_, 0, 0, size.width(), size.height(), FALSE)) {
- return false;
- }
- size_ = size;
- if (has_alpha == alpha_) {
- // A 0-size PostSubBuffer doesn't swap but forces the swap chain to resize
- // to match the window.
- PostSubBuffer(0, 0, 0, 0);
- } else {
- alpha_ = has_alpha;
- config_ = nullptr;
-
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
- gfx::GLContext* current_context = gfx::GLContext::GetCurrent();
- bool was_current = current_context && current_context->IsCurrent(this);
- if (was_current) {
- scoped_make_current.reset(
- new ui::ScopedMakeCurrent(current_context, this));
- current_context->ReleaseCurrent(this);
- }
-
- Destroy();
-
- if (!Initialize()) {
- LOG(ERROR) << "Failed to resize window.";
- return false;
- }
- }
- return true;
- }
-}
-
-gfx::SwapResult ChildWindowSurfaceWin::SwapBuffers() {
- gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
- ClearInvalidContents();
- return result;
-}
-
-gfx::SwapResult ChildWindowSurfaceWin::PostSubBuffer(int x,
- int y,
- int width,
- int height) {
- gfx::SwapResult result =
- NativeViewGLSurfaceEGL::PostSubBuffer(x, y, width, height);
- ClearInvalidContents();
- return result;
-}
-
-void ChildWindowSurfaceWin::InvalidateWindowRect(const gfx::Rect& rect) {
- rect_to_clear_.Union(rect);
-}
-
-void ChildWindowSurfaceWin::ClearInvalidContents() {
- if (!rect_to_clear_.IsEmpty()) {
- base::win::ScopedGetDC dc(window_);
-
- RECT rect = rect_to_clear_.ToRECT();
-
- // DirectComposition composites with the contents under the SwapChain,
- // so ensure that's cleared. GDI treats black as transparent.
- FillRect(dc, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
- rect_to_clear_ = gfx::Rect();
- }
-}
-
-ChildWindowSurfaceWin::~ChildWindowSurfaceWin() {
- gfx::SetWindowUserData(window_, nullptr);
- DestroyWindow(window_);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/child_window_surface_win.h b/chromium/content/common/gpu/child_window_surface_win.h
deleted file mode 100644
index 83acd88ae49..00000000000
--- a/chromium/content/common/gpu/child_window_surface_win.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_GPU_CHILD_WINDOW_SURFACE_WIN_H_
-#define CONTENT_COMMON_GPU_CHILD_WINDOW_SURFACE_WIN_H_
-#include "ui/gl/gl_surface_egl.h"
-
-#include <windows.h>
-
-namespace content {
-
-class GpuChannelManager;
-
-class ChildWindowSurfaceWin : public gfx::NativeViewGLSurfaceEGL {
- public:
- ChildWindowSurfaceWin(GpuChannelManager* manager, HWND parent_window);
-
- // GLSurface implementation.
- EGLConfig GetConfig() override;
- bool Resize(const gfx::Size& size,
- float scale_factor,
- bool has_alpha) override;
- bool InitializeNativeWindow() override;
- gfx::SwapResult SwapBuffers() override;
- gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
-
- void InvalidateWindowRect(const gfx::Rect& rect);
-
- protected:
- ~ChildWindowSurfaceWin() override;
-
- private:
- void ClearInvalidContents();
-
- HWND parent_window_;
- GpuChannelManager* manager_;
- gfx::Rect rect_to_clear_;
-
- DISALLOW_COPY_AND_ASSIGN(ChildWindowSurfaceWin);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CHILD_WINDOW_SURFACE_WIN_H_
diff --git a/chromium/content/common/gpu/client/DEPS b/chromium/content/common/gpu/client/DEPS
index 1aea6635f14..409909c2df0 100644
--- a/chromium/content/common/gpu/client/DEPS
+++ b/chromium/content/common/gpu/client/DEPS
@@ -1,10 +1,3 @@
include_rules = [
"+cc/blink",
]
-
-specific_include_rules = {
- # Tests can make use of content/browser/ infrastructure.
- ".*browsertest\.cc": [
- "+content/browser"
- ]
-}
diff --git a/chromium/content/common/gpu/client/command_buffer_metrics.cc b/chromium/content/common/gpu/client/command_buffer_metrics.cc
index 38590c36c08..2ff84f8b1f8 100644
--- a/chromium/content/common/gpu/client/command_buffer_metrics.cc
+++ b/chromium/content/common/gpu/client/command_buffer_metrics.cc
@@ -75,7 +75,7 @@ CommandBufferContextLostReason GetContextLostReason(
void RecordContextLost(CommandBufferContextType type,
CommandBufferContextLostReason reason) {
switch (type) {
- case BROWSER_COMPOSITOR_ONSCREEN_CONTEXT:
+ case DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT:
UMA_HISTOGRAM_ENUMERATION("GPU.ContextLost.BrowserCompositor", reason,
CONTEXT_LOST_REASON_MAX_ENUM);
break;
@@ -124,8 +124,8 @@ std::string CommandBufferContextTypeToString(CommandBufferContextType type) {
switch (type) {
case OFFSCREEN_CONTEXT_FOR_TESTING:
return "Context-For-Testing";
- case BROWSER_COMPOSITOR_ONSCREEN_CONTEXT:
- return "Compositor";
+ case DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT:
+ return "DisplayCompositor";
case BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT:
return "Offscreen-MainThread";
case BROWSER_WORKER_CONTEXT:
diff --git a/chromium/content/common/gpu/client/command_buffer_metrics.h b/chromium/content/common/gpu/client/command_buffer_metrics.h
index 0b4790cd4b0..0cd62bb2209 100644
--- a/chromium/content/common/gpu/client/command_buffer_metrics.h
+++ b/chromium/content/common/gpu/client/command_buffer_metrics.h
@@ -12,7 +12,7 @@
namespace content {
enum CommandBufferContextType {
- BROWSER_COMPOSITOR_ONSCREEN_CONTEXT,
+ DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT,
BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT,
BROWSER_WORKER_CONTEXT,
RENDER_COMPOSITOR_CONTEXT,
diff --git a/chromium/content/common/gpu/client/command_buffer_proxy_impl.cc b/chromium/content/common/gpu/client/command_buffer_proxy_impl.cc
deleted file mode 100644
index 1b5d14b2ff4..00000000000
--- a/chromium/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ /dev/null
@@ -1,820 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/client/command_buffer_proxy_impl.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory.h"
-#include "base/stl_util.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/child_process_messages.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
-#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/view_messages.h"
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
-#include "gpu/command_buffer/common/cmd_buffer_common.h"
-#include "gpu/command_buffer/common/command_buffer_shared.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/gl_bindings.h"
-
-namespace content {
-
-namespace {
-
-uint64_t CommandBufferProxyID(int channel_id, int32_t route_id) {
- return (static_cast<uint64_t>(channel_id) << 32) | route_id;
-}
-
-} // namespace
-
-CommandBufferProxyImpl::CommandBufferProxyImpl(GpuChannelHost* channel,
- int32_t route_id,
- int32_t stream_id)
- : lock_(nullptr),
- channel_(channel),
- command_buffer_id_(CommandBufferProxyID(channel->channel_id(), route_id)),
- route_id_(route_id),
- stream_id_(stream_id),
- flush_count_(0),
- last_put_offset_(-1),
- last_barrier_put_offset_(-1),
- next_fence_sync_release_(1),
- flushed_fence_sync_release_(0),
- verified_fence_sync_release_(0),
- next_signal_id_(0),
- weak_this_(AsWeakPtr()),
- callback_thread_(base::ThreadTaskRunnerHandle::Get()) {
- DCHECK(channel);
- DCHECK(stream_id);
-}
-
-CommandBufferProxyImpl::~CommandBufferProxyImpl() {
- FOR_EACH_OBSERVER(DeletionObserver,
- deletion_observers_,
- OnWillDeleteImpl());
- if (channel_) {
- channel_->DestroyCommandBuffer(this);
- channel_ = nullptr;
- }
-}
-
-bool CommandBufferProxyImpl::OnMessageReceived(const IPC::Message& message) {
- scoped_ptr<base::AutoLock> lock;
- if (lock_)
- lock.reset(new base::AutoLock(*lock_));
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(CommandBufferProxyImpl, message)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Destroyed, OnDestroyed);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ConsoleMsg, OnConsoleMessage);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalAck,
- OnSignalAck);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SwapBuffersCompleted,
- OnSwapBuffersCompleted);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateVSyncParameters,
- OnUpdateVSyncParameters);
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- if (!handled) {
- DLOG(ERROR) << "Gpu process sent invalid message.";
- InvalidGpuMessage();
- }
- return handled;
-}
-
-void CommandBufferProxyImpl::OnChannelError() {
- scoped_ptr<base::AutoLock> lock;
- if (lock_)
- lock.reset(new base::AutoLock(*lock_));
-
- gpu::error::ContextLostReason context_lost_reason =
- gpu::error::kGpuChannelLost;
- if (shared_state_shm_ && shared_state_shm_->memory()) {
- TryUpdateState();
- // The GPU process might have intentionally been crashed
- // (exit_on_context_lost), so try to find out the original reason.
- if (last_state_.error == gpu::error::kLostContext)
- context_lost_reason = last_state_.context_lost_reason;
- }
- OnDestroyed(context_lost_reason, gpu::error::kLostContext);
-}
-
-void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason,
- gpu::error::Error error) {
- CheckLock();
- // Prevent any further messages from being sent.
- if (channel_) {
- channel_->DestroyCommandBuffer(this);
- channel_ = nullptr;
- }
-
- // When the client sees that the context is lost, they should delete this
- // CommandBufferProxyImpl and create a new one.
- last_state_.error = error;
- last_state_.context_lost_reason = reason;
-
- if (!context_lost_callback_.is_null()) {
- context_lost_callback_.Run();
- // Avoid calling the error callback more than once.
- context_lost_callback_.Reset();
- }
-}
-
-void CommandBufferProxyImpl::OnConsoleMessage(
- const GPUCommandBufferConsoleMessage& message) {
- if (!console_message_callback_.is_null()) {
- console_message_callback_.Run(message.message, message.id);
- }
-}
-
-void CommandBufferProxyImpl::AddDeletionObserver(DeletionObserver* observer) {
- scoped_ptr<base::AutoLock> lock;
- if (lock_)
- lock.reset(new base::AutoLock(*lock_));
- deletion_observers_.AddObserver(observer);
-}
-
-void CommandBufferProxyImpl::RemoveDeletionObserver(
- DeletionObserver* observer) {
- scoped_ptr<base::AutoLock> lock;
- if (lock_)
- lock.reset(new base::AutoLock(*lock_));
- deletion_observers_.RemoveObserver(observer);
-}
-
-void CommandBufferProxyImpl::OnSignalAck(uint32_t id) {
- SignalTaskMap::iterator it = signal_tasks_.find(id);
- if (it == signal_tasks_.end()) {
- DLOG(ERROR) << "Gpu process sent invalid SignalAck.";
- InvalidGpuMessage();
- return;
- }
- base::Closure callback = it->second;
- signal_tasks_.erase(it);
- callback.Run();
-}
-
-void CommandBufferProxyImpl::SetContextLostCallback(
- const base::Closure& callback) {
- CheckLock();
- context_lost_callback_ = callback;
-}
-
-bool CommandBufferProxyImpl::Initialize() {
- TRACE_EVENT0("gpu", "CommandBufferProxyImpl::Initialize");
- shared_state_shm_.reset(channel_->factory()->AllocateSharedMemory(
- sizeof(*shared_state())).release());
- if (!shared_state_shm_)
- return false;
-
- if (!shared_state_shm_->Map(sizeof(*shared_state())))
- return false;
-
- shared_state()->Initialize();
-
- // This handle is owned by the GPU process and must be passed to it or it
- // will leak. In otherwords, do not early out on error between here and the
- // sending of the Initialize IPC below.
- base::SharedMemoryHandle handle =
- channel_->ShareToGpuProcess(shared_state_shm_->handle());
- if (!base::SharedMemory::IsHandleValid(handle))
- return false;
-
- bool result = false;
- if (!Send(new GpuCommandBufferMsg_Initialize(
- route_id_, handle, &result, &capabilities_))) {
- LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize.";
- return false;
- }
-
- if (!result) {
- LOG(ERROR) << "Failed to initialize command buffer service.";
- return false;
- }
-
- capabilities_.image = true;
-
- return true;
-}
-
-gpu::CommandBuffer::State CommandBufferProxyImpl::GetLastState() {
- return last_state_;
-}
-
-int32_t CommandBufferProxyImpl::GetLastToken() {
- TryUpdateState();
- return last_state_.token;
-}
-
-void CommandBufferProxyImpl::Flush(int32_t put_offset) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- TRACE_EVENT1("gpu",
- "CommandBufferProxyImpl::Flush",
- "put_offset",
- put_offset);
-
- bool put_offset_changed = last_put_offset_ != put_offset;
- last_put_offset_ = put_offset;
- last_barrier_put_offset_ = put_offset;
-
- if (channel_) {
- const uint32_t flush_id = channel_->OrderingBarrier(
- route_id_, stream_id_, put_offset, ++flush_count_, latency_info_,
- put_offset_changed, true);
- if (put_offset_changed) {
- DCHECK(flush_id);
- const uint64_t fence_sync_release = next_fence_sync_release_ - 1;
- if (fence_sync_release > flushed_fence_sync_release_) {
- flushed_fence_sync_release_ = fence_sync_release;
- flushed_release_flush_id_.push(
- std::make_pair(fence_sync_release, flush_id));
- }
- }
- }
-
- if (put_offset_changed)
- latency_info_.clear();
-}
-
-void CommandBufferProxyImpl::OrderingBarrier(int32_t put_offset) {
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- TRACE_EVENT1("gpu", "CommandBufferProxyImpl::OrderingBarrier", "put_offset",
- put_offset);
-
- bool put_offset_changed = last_barrier_put_offset_ != put_offset;
- last_barrier_put_offset_ = put_offset;
-
- if (channel_) {
- const uint32_t flush_id = channel_->OrderingBarrier(
- route_id_, stream_id_, put_offset, ++flush_count_, latency_info_,
- put_offset_changed, false);
- if (put_offset_changed) {
- DCHECK(flush_id);
- const uint64_t fence_sync_release = next_fence_sync_release_ - 1;
- if (fence_sync_release > flushed_fence_sync_release_) {
- flushed_fence_sync_release_ = fence_sync_release;
- flushed_release_flush_id_.push(
- std::make_pair(fence_sync_release, flush_id));
- }
- }
- }
-
- if (put_offset_changed)
- latency_info_.clear();
-}
-
-void CommandBufferProxyImpl::SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) {
- CheckLock();
- for (size_t i = 0; i < latency_info.size(); i++)
- latency_info_.push_back(latency_info[i]);
-}
-
-void CommandBufferProxyImpl::SetSwapBuffersCompletionCallback(
- const SwapBuffersCompletionCallback& callback) {
- CheckLock();
- swap_buffers_completion_callback_ = callback;
-}
-
-void CommandBufferProxyImpl::SetUpdateVSyncParametersCallback(
- const UpdateVSyncParametersCallback& callback) {
- CheckLock();
- update_vsync_parameters_completion_callback_ = callback;
-}
-
-void CommandBufferProxyImpl::WaitForTokenInRange(int32_t start, int32_t end) {
- CheckLock();
- TRACE_EVENT2("gpu",
- "CommandBufferProxyImpl::WaitForToken",
- "start",
- start,
- "end",
- end);
- TryUpdateState();
- if (!InRange(start, end, last_state_.token) &&
- last_state_.error == gpu::error::kNoError) {
- gpu::CommandBuffer::State state;
- if (Send(new GpuCommandBufferMsg_WaitForTokenInRange(
- route_id_, start, end, &state)))
- OnUpdateState(state);
- }
- if (!InRange(start, end, last_state_.token) &&
- last_state_.error == gpu::error::kNoError) {
- DLOG(ERROR) << "GPU state invalid after WaitForTokenInRange.";
- InvalidGpuReply();
- }
-}
-
-void CommandBufferProxyImpl::WaitForGetOffsetInRange(int32_t start,
- int32_t end) {
- CheckLock();
- TRACE_EVENT2("gpu",
- "CommandBufferProxyImpl::WaitForGetOffset",
- "start",
- start,
- "end",
- end);
- TryUpdateState();
- if (!InRange(start, end, last_state_.get_offset) &&
- last_state_.error == gpu::error::kNoError) {
- gpu::CommandBuffer::State state;
- if (Send(new GpuCommandBufferMsg_WaitForGetOffsetInRange(
- route_id_, start, end, &state)))
- OnUpdateState(state);
- }
- if (!InRange(start, end, last_state_.get_offset) &&
- last_state_.error == gpu::error::kNoError) {
- DLOG(ERROR) << "GPU state invalid after WaitForGetOffsetInRange.";
- InvalidGpuReply();
- }
-}
-
-void CommandBufferProxyImpl::SetGetBuffer(int32_t shm_id) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id));
- last_put_offset_ = -1;
-}
-
-scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::CreateTransferBuffer(
- size_t size,
- int32_t* id) {
- CheckLock();
- *id = -1;
-
- if (last_state_.error != gpu::error::kNoError)
- return NULL;
-
- int32_t new_id = channel_->ReserveTransferBufferId();
-
- scoped_ptr<base::SharedMemory> shared_memory(
- channel_->factory()->AllocateSharedMemory(size));
- if (!shared_memory) {
- if (last_state_.error == gpu::error::kNoError)
- last_state_.error = gpu::error::kOutOfBounds;
- return NULL;
- }
-
- DCHECK(!shared_memory->memory());
- if (!shared_memory->Map(size)) {
- if (last_state_.error == gpu::error::kNoError)
- last_state_.error = gpu::error::kOutOfBounds;
- return NULL;
- }
-
- // This handle is owned by the GPU process and must be passed to it or it
- // will leak. In otherwords, do not early out on error between here and the
- // sending of the RegisterTransferBuffer IPC below.
- base::SharedMemoryHandle handle =
- channel_->ShareToGpuProcess(shared_memory->handle());
- if (!base::SharedMemory::IsHandleValid(handle)) {
- if (last_state_.error == gpu::error::kNoError)
- last_state_.error = gpu::error::kLostContext;
- return NULL;
- }
-
- if (!Send(new GpuCommandBufferMsg_RegisterTransferBuffer(route_id_,
- new_id,
- handle,
- size))) {
- return NULL;
- }
-
- *id = new_id;
- scoped_refptr<gpu::Buffer> buffer(
- gpu::MakeBufferFromSharedMemory(std::move(shared_memory), size));
- return buffer;
-}
-
-void CommandBufferProxyImpl::DestroyTransferBuffer(int32_t id) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- Send(new GpuCommandBufferMsg_DestroyTransferBuffer(route_id_, id));
-}
-
-gpu::Capabilities CommandBufferProxyImpl::GetCapabilities() {
- return capabilities_;
-}
-
-int32_t CommandBufferProxyImpl::CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internal_format) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return -1;
-
- int32_t new_id = channel_->ReserveImageId();
-
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager =
- channel_->gpu_memory_buffer_manager();
- gfx::GpuMemoryBuffer* gpu_memory_buffer =
- gpu_memory_buffer_manager->GpuMemoryBufferFromClientBuffer(buffer);
- DCHECK(gpu_memory_buffer);
-
- // This handle is owned by the GPU process and must be passed to it or it
- // will leak. In otherwords, do not early out on error between here and the
- // sending of the CreateImage IPC below.
- bool requires_sync_token = false;
- gfx::GpuMemoryBufferHandle handle =
- channel_->ShareGpuMemoryBufferToGpuProcess(gpu_memory_buffer->GetHandle(),
- &requires_sync_token);
-
- uint64_t image_fence_sync = 0;
- if (requires_sync_token) {
- image_fence_sync = GenerateFenceSyncRelease();
-
- // Make sure fence syncs were flushed before CreateImage() was called.
- DCHECK_LE(image_fence_sync - 1, flushed_fence_sync_release_);
- }
-
- DCHECK(gpu::ImageFactory::IsGpuMemoryBufferFormatSupported(
- gpu_memory_buffer->GetFormat(), capabilities_));
- DCHECK(gpu::ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat(
- gfx::Size(width, height), gpu_memory_buffer->GetFormat()));
- DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
- internal_format, gpu_memory_buffer->GetFormat()));
-
- GpuCommandBufferMsg_CreateImage_Params params;
- params.id = new_id;
- params.gpu_memory_buffer = handle;
- params.size = gfx::Size(width, height);
- params.format = gpu_memory_buffer->GetFormat();
- params.internal_format = internal_format;
- params.image_release_count = image_fence_sync;
-
- if (!Send(new GpuCommandBufferMsg_CreateImage(route_id_, params)))
- return -1;
-
- if (image_fence_sync) {
- gpu::SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(),
- GetCommandBufferID(), image_fence_sync);
-
- // Force a synchronous IPC to validate sync token.
- EnsureWorkVisible();
- sync_token.SetVerifyFlush();
-
- gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer,
- sync_token);
- }
-
- return new_id;
-}
-
-void CommandBufferProxyImpl::DestroyImage(int32_t id) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- Send(new GpuCommandBufferMsg_DestroyImage(route_id_, id));
-}
-
-int32_t CommandBufferProxyImpl::CreateGpuMemoryBufferImage(
- size_t width,
- size_t height,
- unsigned internal_format,
- unsigned usage) {
- CheckLock();
- scoped_ptr<gfx::GpuMemoryBuffer> buffer(
- channel_->gpu_memory_buffer_manager()->AllocateGpuMemoryBuffer(
- gfx::Size(width, height),
- gpu::ImageFactory::DefaultBufferFormatForImageFormat(internal_format),
- gfx::BufferUsage::SCANOUT));
- if (!buffer)
- return -1;
-
- return CreateImage(buffer->AsClientBuffer(), width, height, internal_format);
-}
-
-uint32_t CommandBufferProxyImpl::CreateStreamTexture(uint32_t texture_id) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return 0;
-
- int32_t stream_id = channel_->GenerateRouteID();
- bool succeeded = false;
- Send(new GpuCommandBufferMsg_CreateStreamTexture(
- route_id_, texture_id, stream_id, &succeeded));
- if (!succeeded) {
- DLOG(ERROR) << "GpuCommandBufferMsg_CreateStreamTexture returned failure";
- return 0;
- }
- return stream_id;
-}
-
-void CommandBufferProxyImpl::SetLock(base::Lock* lock) {
- lock_ = lock;
-}
-
-bool CommandBufferProxyImpl::IsGpuChannelLost() {
- return !channel_ || channel_->IsLost();
-}
-
-void CommandBufferProxyImpl::EnsureWorkVisible() {
- if (channel_)
- channel_->ValidateFlushIDReachedServer(stream_id_, true);
-}
-
-gpu::CommandBufferNamespace CommandBufferProxyImpl::GetNamespaceID() const {
- return gpu::CommandBufferNamespace::GPU_IO;
-}
-
-uint64_t CommandBufferProxyImpl::GetCommandBufferID() const {
- return command_buffer_id_;
-}
-
-int32_t CommandBufferProxyImpl::GetExtraCommandBufferData() const {
- return stream_id_;
-}
-
-uint64_t CommandBufferProxyImpl::GenerateFenceSyncRelease() {
- return next_fence_sync_release_++;
-}
-
-bool CommandBufferProxyImpl::IsFenceSyncRelease(uint64_t release) {
- return release != 0 && release < next_fence_sync_release_;
-}
-
-bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) {
- return release != 0 && release <= flushed_fence_sync_release_;
-}
-
-bool CommandBufferProxyImpl::IsFenceSyncFlushReceived(uint64_t release) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return false;
-
- if (release <= verified_fence_sync_release_)
- return true;
-
- // Check if we have actually flushed the fence sync release.
- if (release <= flushed_fence_sync_release_) {
- DCHECK(!flushed_release_flush_id_.empty());
- // Check if it has already been validated by another context.
- UpdateVerifiedReleases(channel_->GetHighestValidatedFlushID(stream_id_));
- if (release <= verified_fence_sync_release_)
- return true;
-
- // Has not been validated, validate it now.
- UpdateVerifiedReleases(
- channel_->ValidateFlushIDReachedServer(stream_id_, false));
- return release <= verified_fence_sync_release_;
- }
-
- return false;
-}
-
-void CommandBufferProxyImpl::SignalSyncToken(const gpu::SyncToken& sync_token,
- const base::Closure& callback) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- uint32_t signal_id = next_signal_id_++;
- if (!Send(new GpuCommandBufferMsg_SignalSyncToken(route_id_,
- sync_token,
- signal_id))) {
- return;
- }
-
- signal_tasks_.insert(std::make_pair(signal_id, callback));
-}
-
-bool CommandBufferProxyImpl::CanWaitUnverifiedSyncToken(
- const gpu::SyncToken* sync_token) {
- // Can only wait on an unverified sync token if it is from the same channel.
- const uint64_t token_channel = sync_token->command_buffer_id() >> 32;
- const uint64_t channel = command_buffer_id_ >> 32;
- if (sync_token->namespace_id() != gpu::CommandBufferNamespace::GPU_IO ||
- token_channel != channel) {
- return false;
- }
-
- // If waiting on a different stream, flush pending commands on that stream.
- const int32_t release_stream_id = sync_token->extra_data_field();
- if (release_stream_id == 0)
- return false;
-
- if (release_stream_id != stream_id_)
- channel_->FlushPendingStream(release_stream_id);
-
- return true;
-}
-
-uint32_t CommandBufferProxyImpl::InsertSyncPoint() {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return 0;
-
- uint32_t sync_point = 0;
- Send(new GpuCommandBufferMsg_InsertSyncPoint(route_id_, true, &sync_point));
- return sync_point;
-}
-
-uint32_t CommandBufferProxyImpl::InsertFutureSyncPoint() {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return 0;
-
- uint32_t sync_point = 0;
- Send(new GpuCommandBufferMsg_InsertSyncPoint(route_id_, false, &sync_point));
- return sync_point;
-}
-
-void CommandBufferProxyImpl::RetireSyncPoint(uint32_t sync_point) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- Send(new GpuCommandBufferMsg_RetireSyncPoint(route_id_, sync_point));
-}
-
-void CommandBufferProxyImpl::SignalSyncPoint(uint32_t sync_point,
- const base::Closure& callback) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- uint32_t signal_id = next_signal_id_++;
- if (!Send(new GpuCommandBufferMsg_SignalSyncPoint(route_id_,
- sync_point,
- signal_id))) {
- return;
- }
-
- signal_tasks_.insert(std::make_pair(signal_id, callback));
-}
-
-void CommandBufferProxyImpl::SignalQuery(uint32_t query,
- const base::Closure& callback) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- // Signal identifiers are hidden, so nobody outside of this class will see
- // them. (And thus, they cannot save them.) The IDs themselves only last
- // until the callback is invoked, which will happen as soon as the GPU
- // catches upwith the command buffer.
- // A malicious caller trying to create a collision by making next_signal_id
- // would have to make calls at an astounding rate (300B/s) and even if they
- // could do that, all they would do is to prevent some callbacks from getting
- // called, leading to stalled threads and/or memory leaks.
- uint32_t signal_id = next_signal_id_++;
- if (!Send(new GpuCommandBufferMsg_SignalQuery(route_id_,
- query,
- signal_id))) {
- return;
- }
-
- signal_tasks_.insert(std::make_pair(signal_id, callback));
-}
-
-bool CommandBufferProxyImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) {
- CheckLock();
- if (last_state_.error != gpu::error::kNoError)
- return false;
-
- return Send(new GpuCommandBufferMsg_ProduceFrontBuffer(route_id_, mailbox));
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-CommandBufferProxyImpl::CreateVideoDecoder() {
- if (!channel_)
- return scoped_ptr<media::VideoDecodeAccelerator>();
- return scoped_ptr<media::VideoDecodeAccelerator>(
- new GpuVideoDecodeAcceleratorHost(channel_, this));
-}
-
-scoped_ptr<media::VideoEncodeAccelerator>
-CommandBufferProxyImpl::CreateVideoEncoder() {
- if (!channel_)
- return scoped_ptr<media::VideoEncodeAccelerator>();
- return scoped_ptr<media::VideoEncodeAccelerator>(
- new GpuVideoEncodeAcceleratorHost(channel_, this));
-}
-
-gpu::error::Error CommandBufferProxyImpl::GetLastError() {
- return last_state_.error;
-}
-
-bool CommandBufferProxyImpl::Send(IPC::Message* msg) {
- // Caller should not intentionally send a message if the context is lost.
- DCHECK(last_state_.error == gpu::error::kNoError);
-
- if (channel_) {
- if (channel_->Send(msg)) {
- return true;
- } else {
- // Flag the command buffer as lost. Defer deleting the channel until
- // OnChannelError is called after returning to the message loop in case
- // it is referenced elsewhere.
- DVLOG(1) << "CommandBufferProxyImpl::Send failed. Losing context.";
- last_state_.error = gpu::error::kLostContext;
- return false;
- }
- }
-
- // Callee takes ownership of message, regardless of whether Send is
- // successful. See IPC::Sender.
- delete msg;
- return false;
-}
-
-void CommandBufferProxyImpl::OnUpdateState(
- const gpu::CommandBuffer::State& state) {
- // Handle wraparound. It works as long as we don't have more than 2B state
- // updates in flight across which reordering occurs.
- if (state.generation - last_state_.generation < 0x80000000U)
- last_state_ = state;
-}
-
-void CommandBufferProxyImpl::SetOnConsoleMessageCallback(
- const GpuConsoleMessageCallback& callback) {
- CheckLock();
- console_message_callback_ = callback;
-}
-
-void CommandBufferProxyImpl::TryUpdateState() {
- if (last_state_.error == gpu::error::kNoError)
- shared_state()->Read(&last_state_);
-}
-
-void CommandBufferProxyImpl::UpdateVerifiedReleases(uint32_t verified_flush) {
- while (!flushed_release_flush_id_.empty()) {
- const std::pair<uint64_t, uint32_t>& front_item =
- flushed_release_flush_id_.front();
- if (front_item.second > verified_flush)
- break;
- verified_fence_sync_release_ = front_item.first;
- flushed_release_flush_id_.pop();
- }
-}
-
-gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const {
- return reinterpret_cast<gpu::CommandBufferSharedState*>(
- shared_state_shm_->memory());
-}
-
-void CommandBufferProxyImpl::OnSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result) {
- if (!swap_buffers_completion_callback_.is_null()) {
- if (!ui::LatencyInfo::Verify(
- latency_info, "CommandBufferProxyImpl::OnSwapBuffersCompleted")) {
- swap_buffers_completion_callback_.Run(std::vector<ui::LatencyInfo>(),
- result);
- return;
- }
- swap_buffers_completion_callback_.Run(latency_info, result);
- }
-}
-
-void CommandBufferProxyImpl::OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) {
- if (!update_vsync_parameters_completion_callback_.is_null())
- update_vsync_parameters_completion_callback_.Run(timebase, interval);
-}
-
-void CommandBufferProxyImpl::InvalidGpuMessage() {
- LOG(ERROR) << "Received invalid message from the GPU process.";
- OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
-}
-
-void CommandBufferProxyImpl::InvalidGpuReply() {
- CheckLock();
- LOG(ERROR) << "Received invalid reply from the GPU process.";
- last_state_.error = gpu::error::kLostContext;
- last_state_.context_lost_reason = gpu::error::kInvalidGpuMessage;
- callback_thread_->PostTask(
- FROM_HERE,
- base::Bind(&CommandBufferProxyImpl::InvalidGpuReplyOnClientThread,
- weak_this_));
-}
-
-void CommandBufferProxyImpl::InvalidGpuReplyOnClientThread() {
- scoped_ptr<base::AutoLock> lock;
- if (lock_)
- lock.reset(new base::AutoLock(*lock_));
- OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/command_buffer_proxy_impl.h b/chromium/content/common/gpu/client/command_buffer_proxy_impl.h
deleted file mode 100644
index 17589a7538e..00000000000
--- a/chromium/content/common/gpu/client/command_buffer_proxy_impl.h
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_
-#define CONTENT_COMMON_GPU_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <queue>
-#include <string>
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
-#include "gpu/command_buffer/client/gpu_control.h"
-#include "gpu/command_buffer/common/command_buffer.h"
-#include "gpu/command_buffer/common/command_buffer_shared.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "ipc/ipc_listener.h"
-#include "ui/events/latency_info.h"
-#include "ui/gfx/swap_result.h"
-
-struct GPUCommandBufferConsoleMessage;
-
-namespace base {
-class SharedMemory;
-}
-
-namespace gpu {
-struct Mailbox;
-struct SyncToken;
-}
-
-namespace media {
-class VideoDecodeAccelerator;
-class VideoEncodeAccelerator;
-}
-
-namespace content {
-class GpuChannelHost;
-
-// Client side proxy that forwards messages synchronously to a
-// CommandBufferStub.
-class CommandBufferProxyImpl
- : public gpu::CommandBuffer,
- public gpu::GpuControl,
- public IPC::Listener,
- public base::SupportsWeakPtr<CommandBufferProxyImpl> {
- public:
- class DeletionObserver {
- public:
- // Called during the destruction of the CommandBufferProxyImpl.
- virtual void OnWillDeleteImpl() = 0;
-
- protected:
- virtual ~DeletionObserver() {}
- };
-
- typedef base::Callback<void(
- const std::string& msg, int id)> GpuConsoleMessageCallback;
-
- CommandBufferProxyImpl(GpuChannelHost* channel,
- int32_t route_id,
- int32_t stream_id);
- ~CommandBufferProxyImpl() override;
-
- // Sends an IPC message to create a GpuVideoDecodeAccelerator. Creates and
- // returns it as an owned pointer to a media::VideoDecodeAccelerator. Returns
- // NULL on failure to create the GpuVideoDecodeAcceleratorHost.
- // Note that the GpuVideoDecodeAccelerator may still fail to be created in
- // the GPU process, even if this returns non-NULL. In this case the VDA client
- // is notified of an error later, after Initialize().
- scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder();
-
- // Sends an IPC message to create a GpuVideoEncodeAccelerator. Creates and
- // returns it as an owned pointer to a media::VideoEncodeAccelerator. Returns
- // NULL on failure to create the GpuVideoEncodeAcceleratorHost.
- // Note that the GpuVideoEncodeAccelerator may still fail to be created in
- // the GPU process, even if this returns non-NULL. In this case the VEA client
- // is notified of an error later, after Initialize();
- scoped_ptr<media::VideoEncodeAccelerator> CreateVideoEncoder();
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelError() override;
-
- // CommandBuffer implementation:
- bool Initialize() override;
- State GetLastState() override;
- int32_t GetLastToken() override;
- void Flush(int32_t put_offset) override;
- void OrderingBarrier(int32_t put_offset) override;
- void WaitForTokenInRange(int32_t start, int32_t end) override;
- void WaitForGetOffsetInRange(int32_t start, int32_t end) override;
- void SetGetBuffer(int32_t shm_id) override;
- scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
- int32_t* id) override;
- void DestroyTransferBuffer(int32_t id) override;
-
- // gpu::GpuControl implementation:
- gpu::Capabilities GetCapabilities() override;
- int32_t CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internal_format) override;
- void DestroyImage(int32_t id) override;
- int32_t CreateGpuMemoryBufferImage(size_t width,
- size_t height,
- unsigned internal_format,
- unsigned usage) override;
- uint32_t InsertSyncPoint() override;
- uint32_t InsertFutureSyncPoint() override;
- void RetireSyncPoint(uint32_t sync_point) override;
- void SignalSyncPoint(uint32_t sync_point,
- const base::Closure& callback) override;
- void SignalQuery(uint32_t query, const base::Closure& callback) override;
- void SetLock(base::Lock* lock) override;
- bool IsGpuChannelLost() override;
- void EnsureWorkVisible() override;
- gpu::CommandBufferNamespace GetNamespaceID() const override;
- uint64_t GetCommandBufferID() const override;
- int32_t GetExtraCommandBufferData() const override;
- uint64_t GenerateFenceSyncRelease() override;
- bool IsFenceSyncRelease(uint64_t release) override;
- bool IsFenceSyncFlushed(uint64_t release) override;
- bool IsFenceSyncFlushReceived(uint64_t release) override;
- void SignalSyncToken(const gpu::SyncToken& sync_token,
- const base::Closure& callback) override;
- bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override;
-
- bool ProduceFrontBuffer(const gpu::Mailbox& mailbox);
- void SetContextLostCallback(const base::Closure& callback);
-
- void AddDeletionObserver(DeletionObserver* observer);
- void RemoveDeletionObserver(DeletionObserver* observer);
-
- bool EnsureBackbuffer();
-
- void SetOnConsoleMessageCallback(
- const GpuConsoleMessageCallback& callback);
-
- void SetLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
- using SwapBuffersCompletionCallback =
- base::Callback<void(const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result)>;
- void SetSwapBuffersCompletionCallback(
- const SwapBuffersCompletionCallback& callback);
-
- using UpdateVSyncParametersCallback =
- base::Callback<void(base::TimeTicks timebase, base::TimeDelta interval)>;
- void SetUpdateVSyncParametersCallback(
- const UpdateVSyncParametersCallback& callback);
-
- // TODO(apatrick): this is a temporary optimization while skia is calling
- // ContentGLContext::MakeCurrent prior to every GL call. It saves returning 6
- // ints redundantly when only the error is needed for the
- // CommandBufferProxyImpl implementation.
- gpu::error::Error GetLastError() override;
-
- int32_t route_id() const { return route_id_; }
-
- int32_t stream_id() const { return stream_id_; }
-
- GpuChannelHost* channel() const { return channel_; }
-
- base::SharedMemoryHandle GetSharedStateHandle() const {
- return shared_state_shm_->handle();
- }
- uint32_t CreateStreamTexture(uint32_t texture_id);
-
- private:
- typedef std::map<int32_t, scoped_refptr<gpu::Buffer>> TransferBufferMap;
- typedef base::hash_map<uint32_t, base::Closure> SignalTaskMap;
-
- void CheckLock() {
- if (lock_)
- lock_->AssertAcquired();
- }
-
- // Send an IPC message over the GPU channel. This is private to fully
- // encapsulate the channel; all callers of this function must explicitly
- // verify that the context has not been lost.
- bool Send(IPC::Message* msg);
-
- // Message handlers:
- void OnUpdateState(const gpu::CommandBuffer::State& state);
- void OnDestroyed(gpu::error::ContextLostReason reason,
- gpu::error::Error error);
- void OnConsoleMessage(const GPUCommandBufferConsoleMessage& message);
- void OnSignalAck(uint32_t id);
- void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result);
- void OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
-
- // Try to read an updated copy of the state from shared memory.
- void TryUpdateState();
-
- // Updates the highest verified release fence sync.
- void UpdateVerifiedReleases(uint32_t verified_flush);
-
- // Loses the context after we received an invalid message from the GPU
- // process. Will call the lost context callback reentrantly if any.
- void InvalidGpuMessage();
-
- // Loses the context after we received an invalid reply from the GPU
- // process. Will post a task to call the lost context callback if any.
- void InvalidGpuReply();
-
- void InvalidGpuReplyOnClientThread();
-
- // The shared memory area used to update state.
- gpu::CommandBufferSharedState* shared_state() const;
-
- base::Lock* lock_;
-
- // Unowned list of DeletionObservers.
- base::ObserverList<DeletionObserver> deletion_observers_;
-
- // The last cached state received from the service.
- State last_state_;
-
- // The shared memory area used to update state.
- scoped_ptr<base::SharedMemory> shared_state_shm_;
-
- // |*this| is owned by |*channel_| and so is always outlived by it, so using a
- // raw pointer is ok.
- GpuChannelHost* channel_;
- const uint64_t command_buffer_id_;
- const int32_t route_id_;
- const int32_t stream_id_;
- uint32_t flush_count_;
- int32_t last_put_offset_;
- int32_t last_barrier_put_offset_;
-
- // Next generated fence sync.
- uint64_t next_fence_sync_release_;
-
- // Unverified flushed fence syncs with their corresponding flush id.
- std::queue<std::pair<uint64_t, uint32_t>> flushed_release_flush_id_;
-
- // Last flushed fence sync release, same as last item in queue if not empty.
- uint64_t flushed_fence_sync_release_;
-
- // Last verified fence sync.
- uint64_t verified_fence_sync_release_;
-
- base::Closure context_lost_callback_;
-
- GpuConsoleMessageCallback console_message_callback_;
-
- // Tasks to be invoked in SignalSyncPoint responses.
- uint32_t next_signal_id_;
- SignalTaskMap signal_tasks_;
-
- gpu::Capabilities capabilities_;
-
- std::vector<ui::LatencyInfo> latency_info_;
-
- SwapBuffersCompletionCallback swap_buffers_completion_callback_;
- UpdateVSyncParametersCallback update_vsync_parameters_completion_callback_;
-
- base::WeakPtr<CommandBufferProxyImpl> weak_this_;
- scoped_refptr<base::SequencedTaskRunner> callback_thread_;
-
- DISALLOW_COPY_AND_ASSIGN(CommandBufferProxyImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_
diff --git a/chromium/content/common/gpu/client/context_provider_command_buffer.cc b/chromium/content/common/gpu/client/context_provider_command_buffer.cc
index 2560d78067b..7ef9e73294e 100644
--- a/chromium/content/common/gpu/client/context_provider_command_buffer.cc
+++ b/chromium/content/common/gpu/client/context_provider_command_buffer.cc
@@ -12,7 +12,7 @@
#include "base/callback_helpers.h"
#include "base/strings/stringprintf.h"
#include "cc/output/managed_memory_policy.h"
-#include "content/common/gpu/client/grcontext_for_webgraphicscontext3d.h"
+#include "content/common/gpu/client/grcontext_for_gles2_interface.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "third_party/skia/include/gpu/GrContext.h"
@@ -23,11 +23,11 @@ class ContextProviderCommandBuffer::LostContextCallbackProxy
public:
explicit LostContextCallbackProxy(ContextProviderCommandBuffer* provider)
: provider_(provider) {
- provider_->WebContext3DNoChecks()->setContextLostCallback(this);
+ provider_->context3d_->setContextLostCallback(this);
}
~LostContextCallbackProxy() override {
- provider_->WebContext3DNoChecks()->setContextLostCallback(NULL);
+ provider_->context3d_->setContextLostCallback(NULL);
}
void onContextLost() override { provider_->OnLostContext(); }
@@ -49,12 +49,11 @@ ContextProviderCommandBuffer::Create(
ContextProviderCommandBuffer::ContextProviderCommandBuffer(
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
CommandBufferContextType type)
- : context_type_(type),
+ : context3d_(std::move(context3d)),
+ context_type_(type),
debug_name_(CommandBufferContextTypeToString(type)) {
- gr_interface_ = skia::AdoptRef(
- new GrGLInterfaceForWebGraphicsContext3D(std::move(context3d)));
DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(gr_interface_->WebContext3D());
+ DCHECK(context3d_);
context_thread_checker_.DetachFromThread();
}
@@ -63,52 +62,42 @@ ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
context_thread_checker_.CalledOnValidThread());
// Destroy references to the context3d_ before leaking it.
- if (WebContext3DNoChecks()->GetCommandBufferProxy())
- WebContext3DNoChecks()->GetCommandBufferProxy()->SetLock(nullptr);
+ if (context3d_->GetCommandBufferProxy())
+ context3d_->GetCommandBufferProxy()->SetLock(nullptr);
lost_context_callback_proxy_.reset();
}
-
-CommandBufferProxyImpl* ContextProviderCommandBuffer::GetCommandBufferProxy() {
- return WebContext3DNoChecks()->GetCommandBufferProxy();
+gpu::CommandBufferProxyImpl*
+ContextProviderCommandBuffer::GetCommandBufferProxy() {
+ return context3d_->GetCommandBufferProxy();
}
WebGraphicsContext3DCommandBufferImpl*
ContextProviderCommandBuffer::WebContext3D() {
- DCHECK(gr_interface_);
- DCHECK(gr_interface_->WebContext3D());
+ DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
DCHECK(context_thread_checker_.CalledOnValidThread());
- return WebContext3DNoChecks();
-}
-
-WebGraphicsContext3DCommandBufferImpl*
- ContextProviderCommandBuffer::WebContext3DNoChecks() {
- DCHECK(gr_interface_);
- return static_cast<WebGraphicsContext3DCommandBufferImpl*>(
- gr_interface_->WebContext3D());
+ return context3d_.get();
}
bool ContextProviderCommandBuffer::BindToCurrentThread() {
// This is called on the thread the context will be used.
DCHECK(context_thread_checker_.CalledOnValidThread());
- DCHECK(gr_interface_ && gr_interface_->WebContext3D());
if (lost_context_callback_proxy_)
return true;
- WebContext3DNoChecks()->SetContextType(context_type_);
- if (!WebContext3DNoChecks()->InitializeOnCurrentThread())
+ context3d_->SetContextType(context_type_);
+ if (!context3d_->InitializeOnCurrentThread())
return false;
- gr_interface_->BindToCurrentThread();
InitializeCapabilities();
std::string unique_context_name =
- base::StringPrintf("%s-%p", debug_name_.c_str(), WebContext3DNoChecks());
- WebContext3DNoChecks()->traceBeginCHROMIUM("gpu_toplevel",
- unique_context_name.c_str());
+ base::StringPrintf("%s-%p", debug_name_.c_str(), context3d_.get());
+ context3d_->GetGLInterface()->TraceBeginCHROMIUM("gpu_toplevel",
+ unique_context_name.c_str());
lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this));
return true;
@@ -119,13 +108,15 @@ void ContextProviderCommandBuffer::DetachFromThread() {
}
gpu::gles2::GLES2Interface* ContextProviderCommandBuffer::ContextGL() {
+ DCHECK(context3d_);
DCHECK(lost_context_callback_proxy_); // Is bound to thread.
+ DCHECK(context_thread_checker_.CalledOnValidThread());
- return WebContext3D()->GetImplementation();
+ return context3d_->GetImplementation();
}
gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() {
- return WebContext3DNoChecks()->GetContextSupport();
+ return context3d_->GetContextSupport();
}
class GrContext* ContextProviderCommandBuffer::GrContext() {
@@ -135,7 +126,8 @@ class GrContext* ContextProviderCommandBuffer::GrContext() {
if (gr_context_)
return gr_context_->get();
- gr_context_.reset(new GrContextForWebGraphicsContext3D(gr_interface_));
+ gr_context_.reset(
+ new GrContextForGLES2Interface(context3d_->GetGLInterface()));
// If GlContext is already lost, also abandon the new GrContext.
if (gr_context_->get() &&
@@ -154,7 +146,8 @@ void ContextProviderCommandBuffer::InvalidateGrContext(uint32_t state) {
}
void ContextProviderCommandBuffer::SetupLock() {
- WebContext3D()->GetCommandBufferProxy()->SetLock(&context_lock_);
+ DCHECK(context3d_);
+ context3d_->GetCommandBufferProxy()->SetLock(&context_lock_);
}
base::Lock* ContextProviderCommandBuffer::GetLock() {
@@ -187,9 +180,9 @@ void ContextProviderCommandBuffer::OnLostContext() {
void ContextProviderCommandBuffer::InitializeCapabilities() {
Capabilities caps;
- caps.gpu = WebContext3DNoChecks()->GetImplementation()->capabilities();
+ caps.gpu = context3d_->GetImplementation()->capabilities();
- size_t mapped_memory_limit = WebContext3DNoChecks()->GetMappedMemoryLimit();
+ size_t mapped_memory_limit = context3d_->GetMappedMemoryLimit();
caps.max_transfer_buffer_usage_bytes =
mapped_memory_limit == WebGraphicsContext3DCommandBufferImpl::kNoLimit
? std::numeric_limits<size_t>::max() : mapped_memory_limit;
diff --git a/chromium/content/common/gpu/client/context_provider_command_buffer.h b/chromium/content/common/gpu/client/context_provider_command_buffer.h
index 564e76c4040..65b0e50dc7e 100644
--- a/chromium/content/common/gpu/client/context_provider_command_buffer.h
+++ b/chromium/content/common/gpu/client/context_provider_command_buffer.h
@@ -16,12 +16,10 @@
#include "content/common/content_export.h"
#include "content/common/gpu/client/command_buffer_metrics.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
-#include "skia/ext/refptr.h"
namespace content {
-class GrContextForWebGraphicsContext3D;
-class GrGLInterfaceForWebGraphicsContext3D;
+class GrContextForGLES2Interface;
// Implementation of cc::ContextProvider that provides a
// WebGraphicsContext3DCommandBufferImpl context and a GrContext.
@@ -32,7 +30,7 @@ class CONTENT_EXPORT ContextProviderCommandBuffer
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
CommandBufferContextType type);
- CommandBufferProxyImpl* GetCommandBufferProxy();
+ gpu::CommandBufferProxyImpl* GetCommandBufferProxy();
// cc_blink::ContextProviderWebContext implementation.
WebGraphicsContext3DCommandBufferImpl* WebContext3D() override;
@@ -60,14 +58,13 @@ class CONTENT_EXPORT ContextProviderCommandBuffer
void OnLostContext();
private:
- WebGraphicsContext3DCommandBufferImpl* WebContext3DNoChecks();
void InitializeCapabilities();
base::ThreadChecker main_thread_checker_;
base::ThreadChecker context_thread_checker_;
- skia::RefPtr<GrGLInterfaceForWebGraphicsContext3D> gr_interface_;
- scoped_ptr<GrContextForWebGraphicsContext3D> gr_context_;
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d_;
+ scoped_ptr<GrContextForGLES2Interface> gr_context_;
cc::ContextProvider::Capabilities capabilities_;
CommandBufferContextType context_type_;
@@ -78,7 +75,6 @@ class CONTENT_EXPORT ContextProviderCommandBuffer
base::Lock context_lock_;
class LostContextCallbackProxy;
- friend class LostContextCallbackProxy;
scoped_ptr<LostContextCallbackProxy> lost_context_callback_proxy_;
};
diff --git a/chromium/content/common/gpu/client/gl_helper.cc b/chromium/content/common/gpu/client/gl_helper.cc
deleted file mode 100644
index 5549caaacb8..00000000000
--- a/chromium/content/common/gpu/client/gl_helper.cc
+++ /dev/null
@@ -1,1391 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/client/gl_helper.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <queue>
-#include <string>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_util.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/client/gl_helper_readback_support.h"
-#include "content/common/gpu/client/gl_helper_scaling.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace {
-
-class ScopedFlush {
- public:
- explicit ScopedFlush(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
-
- ~ScopedFlush() { gl_->Flush(); }
-
- private:
- gpu::gles2::GLES2Interface* gl_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedFlush);
-};
-
-// Helper class for allocating and holding an RGBA texture of a given
-// size and an associated framebuffer.
-class TextureFrameBufferPair {
- public:
- TextureFrameBufferPair(GLES2Interface* gl, gfx::Size size)
- : texture_(gl), framebuffer_(gl), size_(size) {
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_);
- gl->TexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- size.width(),
- size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- NULL);
- content::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- gl, framebuffer_);
- gl->FramebufferTexture2D(
- GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0);
- }
-
- GLuint texture() const { return texture_.id(); }
- GLuint framebuffer() const { return framebuffer_.id(); }
- gfx::Size size() const { return size_; }
-
- private:
- content::ScopedTexture texture_;
- content::ScopedFramebuffer framebuffer_;
- gfx::Size size_;
-
- DISALLOW_COPY_AND_ASSIGN(TextureFrameBufferPair);
-};
-
-// Helper class for holding a scaler, a texture for the output of that
-// scaler and an associated frame buffer. This is inteded to be used
-// when the output of a scaler is to be sent to a readback.
-class ScalerHolder {
- public:
- ScalerHolder(GLES2Interface* gl, content::GLHelper::ScalerInterface* scaler)
- : texture_and_framebuffer_(gl, scaler->DstSize()), scaler_(scaler) {}
-
- void Scale(GLuint src_texture) {
- scaler_->Scale(src_texture, texture_and_framebuffer_.texture());
- }
-
- content::GLHelper::ScalerInterface* scaler() const { return scaler_.get(); }
- TextureFrameBufferPair* texture_and_framebuffer() {
- return &texture_and_framebuffer_;
- }
- GLuint texture() const { return texture_and_framebuffer_.texture(); }
-
- private:
- TextureFrameBufferPair texture_and_framebuffer_;
- scoped_ptr<content::GLHelper::ScalerInterface> scaler_;
-
- DISALLOW_COPY_AND_ASSIGN(ScalerHolder);
-};
-
-} // namespace
-
-namespace content {
-typedef GLHelperReadbackSupport::FormatSupport FormatSupport;
-
-// Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates
-// the data needed for it.
-class GLHelper::CopyTextureToImpl
- : public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> {
- public:
- CopyTextureToImpl(GLES2Interface* gl,
- gpu::ContextSupport* context_support,
- GLHelper* helper)
- : gl_(gl),
- context_support_(context_support),
- helper_(helper),
- flush_(gl),
- max_draw_buffers_(0) {
- const GLubyte* extensions = gl_->GetString(GL_EXTENSIONS);
- if (!extensions)
- return;
- std::string extensions_string =
- " " + std::string(reinterpret_cast<const char*>(extensions)) + " ";
- if (extensions_string.find(" GL_EXT_draw_buffers ") != std::string::npos) {
- gl_->GetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &max_draw_buffers_);
- }
- }
- ~CopyTextureToImpl() { CancelRequests(); }
-
- GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token) {
- return helper_->ConsumeMailboxToTexture(mailbox, sync_token);
- }
-
- void CropScaleReadbackAndCleanTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality);
-
- void ReadbackTextureSync(GLuint texture,
- const gfx::Rect& src_rect,
- unsigned char* out,
- SkColorType format);
-
- void ReadbackTextureAsync(GLuint texture,
- const gfx::Size& dst_size,
- unsigned char* out,
- SkColorType color_type,
- const base::Callback<void(bool)>& callback);
-
- // Reads back bytes from the currently bound frame buffer.
- // Note that dst_size is specified in bytes, not pixels.
- void ReadbackAsync(
- const gfx::Size& dst_size,
- int32_t bytes_per_row, // generally dst_size.width() * 4
- int32_t row_stride_bytes, // generally dst_size.width() * 4
- unsigned char* out,
- GLenum format,
- GLenum type,
- size_t bytes_per_pixel,
- const base::Callback<void(bool)>& callback);
-
- void ReadbackPlane(TextureFrameBufferPair* source,
- const scoped_refptr<media::VideoFrame>& target,
- int plane,
- int size_shift,
- const gfx::Rect& paste_rect,
- ReadbackSwizzle swizzle,
- const base::Callback<void(bool)>& callback);
-
- GLuint CopyAndScaleTexture(GLuint texture,
- const gfx::Size& src_size,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- GLHelper::ScalerQuality quality);
-
- ReadbackYUVInterface* CreateReadbackPipelineYUV(
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- bool use_mrt);
-
- // Returns the maximum number of draw buffers available,
- // 0 if GL_EXT_draw_buffers is not available.
- GLint MaxDrawBuffers() const { return max_draw_buffers_; }
-
- FormatSupport GetReadbackConfig(SkColorType color_type,
- bool can_swizzle,
- GLenum* format,
- GLenum* type,
- size_t* bytes_per_pixel);
-
- private:
- // A single request to CropScaleReadbackAndCleanTexture.
- // The main thread can cancel the request, before it's handled by the helper
- // thread, by resetting the texture and pixels fields. Alternatively, the
- // thread marks that it handles the request by resetting the pixels field
- // (meaning it guarantees that the callback with be called).
- // In either case, the callback must be called exactly once, and the texture
- // must be deleted by the main thread gl.
- struct Request {
- Request(const gfx::Size& size_,
- int32_t bytes_per_row_,
- int32_t row_stride_bytes_,
- unsigned char* pixels_,
- const base::Callback<void(bool)>& callback_)
- : done(false),
- size(size_),
- bytes_per_row(bytes_per_row_),
- row_stride_bytes(row_stride_bytes_),
- pixels(pixels_),
- callback(callback_),
- buffer(0),
- query(0) {}
-
- bool done;
- bool result;
- gfx::Size size;
- int bytes_per_row;
- int row_stride_bytes;
- unsigned char* pixels;
- base::Callback<void(bool)> callback;
- GLuint buffer;
- GLuint query;
- };
-
- // We must take care to call the callbacks last, as they may
- // end up destroying the gl_helper and make *this invalid.
- // We stick the finished requests in a stack object that calls
- // the callbacks when it goes out of scope.
- class FinishRequestHelper {
- public:
- FinishRequestHelper() {}
- ~FinishRequestHelper() {
- while (!requests_.empty()) {
- Request* request = requests_.front();
- requests_.pop();
- request->callback.Run(request->result);
- delete request;
- }
- }
- void Add(Request* r) {
- requests_.push(r);
- }
- private:
- std::queue<Request*> requests_;
- DISALLOW_COPY_AND_ASSIGN(FinishRequestHelper);
- };
-
- // A readback pipeline that also converts the data to YUV before
- // reading it back.
- class ReadbackYUVImpl : public ReadbackYUVInterface {
- public:
- ReadbackYUVImpl(GLES2Interface* gl,
- CopyTextureToImpl* copy_impl,
- GLHelperScaling* scaler_impl,
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- ReadbackSwizzle swizzle);
-
- void ReadbackYUV(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- const scoped_refptr<media::VideoFrame>& target,
- const gfx::Point& paste_location,
- const base::Callback<void(bool)>& callback) override;
-
- ScalerInterface* scaler() override { return scaler_.scaler(); }
-
- private:
- GLES2Interface* gl_;
- CopyTextureToImpl* copy_impl_;
- gfx::Size dst_size_;
- ReadbackSwizzle swizzle_;
- ScalerHolder scaler_;
- ScalerHolder y_;
- ScalerHolder u_;
- ScalerHolder v_;
-
- DISALLOW_COPY_AND_ASSIGN(ReadbackYUVImpl);
- };
-
- // A readback pipeline that also converts the data to YUV before
- // reading it back. This one uses Multiple Render Targets, which
- // may not be supported on all platforms.
- class ReadbackYUV_MRT : public ReadbackYUVInterface {
- public:
- ReadbackYUV_MRT(GLES2Interface* gl,
- CopyTextureToImpl* copy_impl,
- GLHelperScaling* scaler_impl,
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- ReadbackSwizzle swizzle);
-
- void ReadbackYUV(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- const scoped_refptr<media::VideoFrame>& target,
- const gfx::Point& paste_location,
- const base::Callback<void(bool)>& callback) override;
-
- ScalerInterface* scaler() override { return scaler_.scaler(); }
-
- private:
- GLES2Interface* gl_;
- CopyTextureToImpl* copy_impl_;
- gfx::Size dst_size_;
- GLHelper::ScalerQuality quality_;
- ReadbackSwizzle swizzle_;
- ScalerHolder scaler_;
- scoped_ptr<content::GLHelperScaling::ShaderInterface> pass1_shader_;
- scoped_ptr<content::GLHelperScaling::ShaderInterface> pass2_shader_;
- TextureFrameBufferPair y_;
- ScopedTexture uv_;
- TextureFrameBufferPair u_;
- TextureFrameBufferPair v_;
-
- DISALLOW_COPY_AND_ASSIGN(ReadbackYUV_MRT);
- };
-
- // Copies the block of pixels specified with |src_subrect| from |src_texture|,
- // scales it to |dst_size|, writes it into a texture, and returns its ID.
- // |src_size| is the size of |src_texture|.
- GLuint ScaleTexture(GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- SkColorType color_type,
- GLHelper::ScalerQuality quality);
-
- // Converts each four consecutive pixels of the source texture into one pixel
- // in the result texture with each pixel channel representing the grayscale
- // color of one of the four original pixels:
- // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X1X2X3X4
- // The resulting texture is still an RGBA texture (which is ~4 times narrower
- // than the original). If rendered directly, it wouldn't show anything useful,
- // but the data in it can be used to construct a grayscale image.
- // |encoded_texture_size| is the exact size of the resulting RGBA texture. It
- // is equal to src_size.width()/4 rounded upwards. Some channels in the last
- // pixel ((-src_size.width()) % 4) to be exact) are padding and don't contain
- // useful data.
- // If swizzle is set to true, the transformed pixels are reordered:
- // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X3X2X1X4.
- GLuint EncodeTextureAsGrayscale(GLuint src_texture,
- const gfx::Size& src_size,
- gfx::Size* const encoded_texture_size,
- bool vertically_flip_texture,
- bool swizzle);
-
- static void nullcallback(bool success) {}
- void ReadbackDone(Request *request, int bytes_per_pixel);
- void FinishRequest(Request* request,
- bool result,
- FinishRequestHelper* helper);
- void CancelRequests();
-
- static const float kRGBtoYColorWeights[];
- static const float kRGBtoUColorWeights[];
- static const float kRGBtoVColorWeights[];
- static const float kRGBtoGrayscaleColorWeights[];
-
- GLES2Interface* gl_;
- gpu::ContextSupport* context_support_;
- GLHelper* helper_;
-
- // A scoped flush that will ensure all resource deletions are flushed when
- // this object is destroyed. Must be declared before other Scoped* fields.
- ScopedFlush flush_;
-
- std::queue<Request*> request_queue_;
- GLint max_draw_buffers_;
-};
-
-GLHelper::ScalerInterface* GLHelper::CreateScaler(ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle) {
- InitScalerImpl();
- return scaler_impl_->CreateScaler(quality,
- src_size,
- src_subrect,
- dst_size,
- vertically_flip_texture,
- swizzle);
-}
-
-GLuint GLHelper::CopyTextureToImpl::ScaleTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- SkColorType color_type,
- GLHelper::ScalerQuality quality) {
- GLuint dst_texture = 0u;
- gl_->GenTextures(1, &dst_texture);
- {
- GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE;
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
-
- // Use GL_RGBA for destination/temporary texture unless we're working with
- // 16-bit data
- if (color_type == kRGB_565_SkColorType) {
- format = GL_RGB;
- type = GL_UNSIGNED_SHORT_5_6_5;
- }
-
- gl_->TexImage2D(GL_TEXTURE_2D,
- 0,
- format,
- dst_size.width(),
- dst_size.height(),
- 0,
- format,
- type,
- NULL);
- }
- scoped_ptr<ScalerInterface> scaler(
- helper_->CreateScaler(quality,
- src_size,
- src_subrect,
- dst_size,
- vertically_flip_texture,
- swizzle));
- scaler->Scale(src_texture, dst_texture);
- return dst_texture;
-}
-
-GLuint GLHelper::CopyTextureToImpl::EncodeTextureAsGrayscale(
- GLuint src_texture,
- const gfx::Size& src_size,
- gfx::Size* const encoded_texture_size,
- bool vertically_flip_texture,
- bool swizzle) {
- GLuint dst_texture = 0u;
- gl_->GenTextures(1, &dst_texture);
- // The size of the encoded texture.
- *encoded_texture_size =
- gfx::Size((src_size.width() + 3) / 4, src_size.height());
- {
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
- gl_->TexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- encoded_texture_size->width(),
- encoded_texture_size->height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- NULL);
- }
-
- helper_->InitScalerImpl();
- scoped_ptr<ScalerInterface> grayscale_scaler(
- helper_->scaler_impl_.get()->CreatePlanarScaler(
- src_size,
- gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()),
- *encoded_texture_size,
- vertically_flip_texture,
- swizzle,
- kRGBtoGrayscaleColorWeights));
- grayscale_scaler->Scale(src_texture, dst_texture);
- return dst_texture;
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackAsync(
- const gfx::Size& dst_size,
- int32_t bytes_per_row,
- int32_t row_stride_bytes,
- unsigned char* out,
- GLenum format,
- GLenum type,
- size_t bytes_per_pixel,
- const base::Callback<void(bool)>& callback) {
- TRACE_EVENT0("gpu.capture", "GLHelper::CopyTextureToImpl::ReadbackAsync");
- Request* request =
- new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback);
- request_queue_.push(request);
- request->buffer = 0u;
-
- gl_->GenBuffers(1, &request->buffer);
- gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer);
- gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
- bytes_per_pixel * dst_size.GetArea(),
- NULL,
- GL_STREAM_READ);
-
- request->query = 0u;
- gl_->GenQueriesEXT(1, &request->query);
- gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query);
- gl_->ReadPixels(0,
- 0,
- dst_size.width(),
- dst_size.height(),
- format,
- type,
- NULL);
- gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM);
- gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
- context_support_->SignalQuery(
- request->query,
- base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(),
- request, bytes_per_pixel));
-}
-
-void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality) {
- GLenum format, type;
- size_t bytes_per_pixel;
- SkColorType readback_color_type = out_color_type;
- // Single-component textures are not supported by all GPUs, so we implement
- // kAlpha_8_SkColorType support here via a special encoding (see below) using
- // a 32-bit texture to represent an 8-bit image.
- // Thus we use generic 32-bit readback in this case.
- if (out_color_type == kAlpha_8_SkColorType) {
- readback_color_type = kRGBA_8888_SkColorType;
- }
-
- FormatSupport supported = GetReadbackConfig(
- readback_color_type, true, &format, &type, &bytes_per_pixel);
-
- if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) {
- callback.Run(false);
- return;
- }
-
- GLuint texture = src_texture;
-
- // Scale texture if needed
- // Optimization: SCALER_QUALITY_FAST is just a single bilinear pass, which we
- // can do just as well in EncodeTextureAsGrayscale, which we will do if
- // out_color_type is kAlpha_8_SkColorType, so let's skip the scaling step
- // in that case.
- bool scale_texture = out_color_type != kAlpha_8_SkColorType ||
- quality != GLHelper::SCALER_QUALITY_FAST;
- if (scale_texture) {
- // Don't swizzle during the scale step for kAlpha_8_SkColorType.
- // We will swizzle in the encode step below if needed.
- bool scale_swizzle = out_color_type == kAlpha_8_SkColorType
- ? false
- : supported == GLHelperReadbackSupport::SWIZZLE;
- texture =
- ScaleTexture(src_texture,
- src_size,
- src_subrect,
- dst_size,
- true,
- scale_swizzle,
- out_color_type == kAlpha_8_SkColorType ? kN32_SkColorType
- : out_color_type,
- quality);
- DCHECK(texture);
- }
-
- gfx::Size readback_texture_size = dst_size;
- // Encode texture to grayscale if needed.
- if (out_color_type == kAlpha_8_SkColorType) {
- // Do the vertical flip here if we haven't already done it when we scaled
- // the texture.
- bool encode_as_grayscale_vertical_flip = !scale_texture;
- // EncodeTextureAsGrayscale by default creates a texture which should be
- // read back as RGBA, so need to swizzle if the readback format is BGRA.
- bool encode_as_grayscale_swizzle = format == GL_BGRA_EXT;
- GLuint tmp_texture =
- EncodeTextureAsGrayscale(texture,
- dst_size,
- &readback_texture_size,
- encode_as_grayscale_vertical_flip,
- encode_as_grayscale_swizzle);
- // If the scaled texture was created - delete it
- if (scale_texture)
- gl_->DeleteTextures(1, &texture);
- texture = tmp_texture;
- DCHECK(texture);
- }
-
- // Readback the pixels of the resulting texture
- ScopedFramebuffer dst_framebuffer(gl_);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
- dst_framebuffer);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- texture,
- 0);
-
- int32_t bytes_per_row = out_color_type == kAlpha_8_SkColorType
- ? dst_size.width()
- : dst_size.width() * bytes_per_pixel;
-
- ReadbackAsync(readback_texture_size,
- bytes_per_row,
- bytes_per_row,
- out,
- format,
- type,
- bytes_per_pixel,
- callback);
- gl_->DeleteTextures(1, &texture);
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackTextureSync(
- GLuint texture,
- const gfx::Rect& src_rect,
- unsigned char* out,
- SkColorType color_type) {
- GLenum format, type;
- size_t bytes_per_pixel;
- FormatSupport supported =
- GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel);
- if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) {
- return;
- }
-
- ScopedFramebuffer dst_framebuffer(gl_);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
- dst_framebuffer);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->FramebufferTexture2D(
- GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
- gl_->ReadPixels(src_rect.x(),
- src_rect.y(),
- src_rect.width(),
- src_rect.height(),
- format,
- type,
- out);
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackTextureAsync(
- GLuint texture,
- const gfx::Size& dst_size,
- unsigned char* out,
- SkColorType color_type,
- const base::Callback<void(bool)>& callback) {
- GLenum format, type;
- size_t bytes_per_pixel;
- FormatSupport supported =
- GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel);
- if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) {
- callback.Run(false);
- return;
- }
-
- ScopedFramebuffer dst_framebuffer(gl_);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
- dst_framebuffer);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- texture,
- 0);
- ReadbackAsync(dst_size,
- dst_size.width() * bytes_per_pixel,
- dst_size.width() * bytes_per_pixel,
- out,
- format,
- type,
- bytes_per_pixel,
- callback);
-}
-
-GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- GLHelper::ScalerQuality quality) {
- return ScaleTexture(src_texture,
- src_size,
- gfx::Rect(src_size),
- dst_size,
- vertically_flip_texture,
- false,
- kRGBA_8888_SkColorType, // GL_RGBA
- quality);
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request,
- int bytes_per_pixel) {
- TRACE_EVENT0("gpu.capture",
- "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete");
- finished_request->done = true;
-
- FinishRequestHelper finish_request_helper;
-
- // We process transfer requests in the order they were received, regardless
- // of the order we get the callbacks in.
- while (!request_queue_.empty()) {
- Request* request = request_queue_.front();
- if (!request->done) {
- break;
- }
-
- bool result = false;
- if (request->buffer != 0) {
- gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer);
- unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM(
- GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
- if (data) {
- result = true;
- if (request->bytes_per_row == request->size.width() * bytes_per_pixel &&
- request->bytes_per_row == request->row_stride_bytes) {
- memcpy(request->pixels, data,
- request->size.GetArea() * bytes_per_pixel);
- } else {
- unsigned char* out = request->pixels;
- for (int y = 0; y < request->size.height(); y++) {
- memcpy(out, data, request->bytes_per_row);
- out += request->row_stride_bytes;
- data += request->size.width() * bytes_per_pixel;
- }
- }
- gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
- }
- gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
- }
- FinishRequest(request, result, &finish_request_helper);
- }
-}
-
-void GLHelper::CopyTextureToImpl::FinishRequest(
- Request* request,
- bool result,
- FinishRequestHelper* finish_request_helper) {
- TRACE_EVENT0("gpu.capture", "GLHelper::CopyTextureToImpl::FinishRequest");
- DCHECK(request_queue_.front() == request);
- request_queue_.pop();
- request->result = result;
- ScopedFlush flush(gl_);
- if (request->query != 0) {
- gl_->DeleteQueriesEXT(1, &request->query);
- request->query = 0;
- }
- if (request->buffer != 0) {
- gl_->DeleteBuffers(1, &request->buffer);
- request->buffer = 0;
- }
- finish_request_helper->Add(request);
-}
-
-void GLHelper::CopyTextureToImpl::CancelRequests() {
- FinishRequestHelper finish_request_helper;
- while (!request_queue_.empty()) {
- Request* request = request_queue_.front();
- FinishRequest(request, false, &finish_request_helper);
- }
-}
-
-FormatSupport GLHelper::CopyTextureToImpl::GetReadbackConfig(
- SkColorType color_type,
- bool can_swizzle,
- GLenum* format,
- GLenum* type,
- size_t* bytes_per_pixel) {
- return helper_->readback_support_->GetReadbackConfig(
- color_type, can_swizzle, format, type, bytes_per_pixel);
-}
-
-GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support)
- : gl_(gl),
- context_support_(context_support),
- readback_support_(new GLHelperReadbackSupport(gl)) {}
-
-GLHelper::~GLHelper() {}
-
-void GLHelper::CropScaleReadbackAndCleanTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality) {
- InitCopyTextToImpl();
- copy_texture_to_impl_->CropScaleReadbackAndCleanTexture(src_texture,
- src_size,
- src_subrect,
- dst_size,
- out,
- out_color_type,
- callback,
- quality);
-}
-
-void GLHelper::CropScaleReadbackAndCleanMailbox(
- const gpu::Mailbox& src_mailbox,
- const gpu::SyncToken& sync_token,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality) {
- GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_token);
- CropScaleReadbackAndCleanTexture(mailbox_texture,
- src_size,
- src_subrect,
- dst_size,
- out,
- out_color_type,
- callback,
- quality);
- gl_->DeleteTextures(1, &mailbox_texture);
-}
-
-void GLHelper::ReadbackTextureSync(GLuint texture,
- const gfx::Rect& src_rect,
- unsigned char* out,
- SkColorType format) {
- InitCopyTextToImpl();
- copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format);
-}
-
-void GLHelper::ReadbackTextureAsync(
- GLuint texture,
- const gfx::Size& dst_size,
- unsigned char* out,
- SkColorType color_type,
- const base::Callback<void(bool)>& callback) {
- InitCopyTextToImpl();
- copy_texture_to_impl_->ReadbackTextureAsync(texture,
- dst_size,
- out,
- color_type,
- callback);
-}
-
-GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) {
- InitCopyTextToImpl();
- return copy_texture_to_impl_->CopyAndScaleTexture(
- texture, size, size, false, GLHelper::SCALER_QUALITY_FAST);
-}
-
-GLuint GLHelper::CopyAndScaleTexture(GLuint texture,
- const gfx::Size& src_size,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- ScalerQuality quality) {
- InitCopyTextToImpl();
- return copy_texture_to_impl_->CopyAndScaleTexture(
- texture, src_size, dst_size, vertically_flip_texture, quality);
-}
-
-GLuint GLHelper::CompileShaderFromSource(const GLchar* source, GLenum type) {
- GLuint shader = gl_->CreateShader(type);
- GLint length = strlen(source);
- gl_->ShaderSource(shader, 1, &source, &length);
- gl_->CompileShader(shader);
- GLint compile_status = 0;
- gl_->GetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
- if (!compile_status) {
- GLint log_length = 0;
- gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
- if (log_length) {
- scoped_ptr<GLchar[]> log(new GLchar[log_length]);
- GLsizei returned_log_length = 0;
- gl_->GetShaderInfoLog(
- shader, log_length, &returned_log_length, log.get());
- LOG(ERROR) << std::string(log.get(), returned_log_length);
- }
- gl_->DeleteShader(shader);
- return 0;
- }
- return shader;
-}
-
-void GLHelper::InitCopyTextToImpl() {
- // Lazily initialize |copy_texture_to_impl_|
- if (!copy_texture_to_impl_)
- copy_texture_to_impl_.reset(
- new CopyTextureToImpl(gl_, context_support_, this));
-}
-
-void GLHelper::InitScalerImpl() {
- // Lazily initialize |scaler_impl_|
- if (!scaler_impl_)
- scaler_impl_.reset(new GLHelperScaling(gl_, this));
-}
-
-GLint GLHelper::MaxDrawBuffers() {
- InitCopyTextToImpl();
- return copy_texture_to_impl_->MaxDrawBuffers();
-}
-
-void GLHelper::CopySubBufferDamage(GLenum target,
- GLuint texture,
- GLuint previous_texture,
- const SkRegion& new_damage,
- const SkRegion& old_damage) {
- SkRegion region(old_damage);
- if (region.op(new_damage, SkRegion::kDifference_Op)) {
- ScopedFramebuffer dst_framebuffer(gl_);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
- dst_framebuffer);
- gl_->BindTexture(target, texture);
- gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
- previous_texture, 0);
- for (SkRegion::Iterator it(region); !it.done(); it.next()) {
- const SkIRect& rect = it.rect();
- gl_->CopyTexSubImage2D(target, 0, rect.x(), rect.y(), rect.x(), rect.y(),
- rect.width(), rect.height());
- }
- gl_->BindTexture(target, 0);
- gl_->Flush();
- }
-}
-
-GLuint GLHelper::CreateTexture() {
- GLuint texture = 0u;
- gl_->GenTextures(1, &texture);
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- return texture;
-}
-
-void GLHelper::DeleteTexture(GLuint texture_id) {
- gl_->DeleteTextures(1, &texture_id);
-}
-
-void GLHelper::GenerateSyncToken(gpu::SyncToken* sync_token) {
- const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
- gl_->ShallowFlushCHROMIUM();
- gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData());
-}
-
-void GLHelper::WaitSyncToken(const gpu::SyncToken& sync_token) {
- gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
-}
-
-gpu::MailboxHolder GLHelper::ProduceMailboxHolderFromTexture(
- GLuint texture_id) {
- gpu::Mailbox mailbox;
- gl_->GenMailboxCHROMIUM(mailbox.name);
- gl_->ProduceTextureDirectCHROMIUM(texture_id, GL_TEXTURE_2D, mailbox.name);
-
- gpu::SyncToken sync_token;
- GenerateSyncToken(&sync_token);
-
- return gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D);
-}
-
-GLuint GLHelper::ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token) {
- if (mailbox.IsZero())
- return 0;
- if (sync_token.HasData())
- WaitSyncToken(sync_token);
- GLuint texture =
- gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
- return texture;
-}
-
-void GLHelper::ResizeTexture(GLuint texture, const gfx::Size& size) {
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->TexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGB,
- size.width(),
- size.height(),
- 0,
- GL_RGB,
- GL_UNSIGNED_BYTE,
- NULL);
-}
-
-void GLHelper::CopyTextureSubImage(GLuint texture, const gfx::Rect& rect) {
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->CopyTexSubImage2D(GL_TEXTURE_2D,
- 0,
- rect.x(),
- rect.y(),
- rect.x(),
- rect.y(),
- rect.width(),
- rect.height());
-}
-
-void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) {
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
- gl_->CopyTexImage2D(
- GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0);
-}
-
-void GLHelper::Flush() {
- gl_->Flush();
-}
-
-void GLHelper::InsertOrderingBarrier() {
- gl_->OrderingBarrierCHROMIUM();
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackPlane(
- TextureFrameBufferPair* source,
- const scoped_refptr<media::VideoFrame>& target,
- int plane,
- int size_shift,
- const gfx::Rect& paste_rect,
- ReadbackSwizzle swizzle,
- const base::Callback<void(bool)>& callback) {
- gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer());
- const size_t offset = target->stride(plane) * (paste_rect.y() >> size_shift) +
- (paste_rect.x() >> size_shift);
- ReadbackAsync(source->size(),
- paste_rect.width() >> size_shift,
- target->stride(plane),
- target->data(plane) + offset,
- (swizzle == kSwizzleBGRA) ? GL_BGRA_EXT : GL_RGBA,
- GL_UNSIGNED_BYTE,
- 4,
- callback);
-}
-
-const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = {
- 0.257f, 0.504f, 0.098f, 0.0625f};
-const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = {
- -0.148f, -0.291f, 0.439f, 0.5f};
-const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = {
- 0.439f, -0.368f, -0.071f, 0.5f};
-const float GLHelper::CopyTextureToImpl::kRGBtoGrayscaleColorWeights[] = {
- 0.213f, 0.715f, 0.072f, 0.0f};
-
-// YUV readback constructors. Initiates the main scaler pipeline and
-// one planar scaler for each of the Y, U and V planes.
-GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl(
- GLES2Interface* gl,
- CopyTextureToImpl* copy_impl,
- GLHelperScaling* scaler_impl,
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- ReadbackSwizzle swizzle)
- : gl_(gl),
- copy_impl_(copy_impl),
- dst_size_(dst_size),
- swizzle_(swizzle),
- scaler_(gl,
- scaler_impl->CreateScaler(quality,
- src_size,
- src_subrect,
- dst_size,
- flip_vertically,
- false)),
- y_(gl,
- scaler_impl->CreatePlanarScaler(
- dst_size,
- gfx::Rect(0,
- 0,
- (dst_size.width() + 3) & ~3,
- dst_size.height()),
- gfx::Size((dst_size.width() + 3) / 4, dst_size.height()),
- false,
- (swizzle == kSwizzleBGRA),
- kRGBtoYColorWeights)),
- u_(gl,
- scaler_impl->CreatePlanarScaler(
- dst_size,
- gfx::Rect(0,
- 0,
- (dst_size.width() + 7) & ~7,
- (dst_size.height() + 1) & ~1),
- gfx::Size((dst_size.width() + 7) / 8,
- (dst_size.height() + 1) / 2),
- false,
- (swizzle == kSwizzleBGRA),
- kRGBtoUColorWeights)),
- v_(gl,
- scaler_impl->CreatePlanarScaler(
- dst_size,
- gfx::Rect(0,
- 0,
- (dst_size.width() + 7) & ~7,
- (dst_size.height() + 1) & ~1),
- gfx::Size((dst_size.width() + 7) / 8,
- (dst_size.height() + 1) / 2),
- false,
- (swizzle == kSwizzleBGRA),
- kRGBtoVColorWeights)) {
- DCHECK(!(dst_size.width() & 1));
- DCHECK(!(dst_size.height() & 1));
-}
-
-static void CallbackKeepingVideoFrameAlive(
- scoped_refptr<media::VideoFrame> video_frame,
- const base::Callback<void(bool)>& callback,
- bool success) {
- callback.Run(success);
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUV(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- const scoped_refptr<media::VideoFrame>& target,
- const gfx::Point& paste_location,
- const base::Callback<void(bool)>& callback) {
- DCHECK(!(paste_location.x() & 1));
- DCHECK(!(paste_location.y() & 1));
-
- GLuint mailbox_texture =
- copy_impl_->ConsumeMailboxToTexture(mailbox, sync_token);
-
- // Scale texture to right size.
- scaler_.Scale(mailbox_texture);
- gl_->DeleteTextures(1, &mailbox_texture);
-
- // Convert the scaled texture in to Y, U and V planes.
- y_.Scale(scaler_.texture());
- u_.Scale(scaler_.texture());
- v_.Scale(scaler_.texture());
-
- const gfx::Rect paste_rect(paste_location, dst_size_);
- if (!target->visible_rect().Contains(paste_rect)) {
- LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!";
- callback.Run(false);
- return;
- }
-
- // Read back planes, one at a time. Keep the video frame alive while doing the
- // readback.
- copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(),
- target,
- media::VideoFrame::kYPlane,
- 0,
- paste_rect,
- swizzle_,
- base::Bind(&nullcallback));
- copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(),
- target,
- media::VideoFrame::kUPlane,
- 1,
- paste_rect,
- swizzle_,
- base::Bind(&nullcallback));
- copy_impl_->ReadbackPlane(
- v_.texture_and_framebuffer(),
- target,
- media::VideoFrame::kVPlane,
- 1,
- paste_rect,
- swizzle_,
- base::Bind(&CallbackKeepingVideoFrameAlive, target, callback));
- gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
- media::LetterboxYUV(target.get(), paste_rect);
-}
-
-// YUV readback constructors. Initiates the main scaler pipeline and
-// one planar scaler for each of the Y, U and V planes.
-GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT(
- GLES2Interface* gl,
- CopyTextureToImpl* copy_impl,
- GLHelperScaling* scaler_impl,
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- ReadbackSwizzle swizzle)
- : gl_(gl),
- copy_impl_(copy_impl),
- dst_size_(dst_size),
- quality_(quality),
- swizzle_(swizzle),
- scaler_(gl,
- scaler_impl->CreateScaler(quality,
- src_size,
- src_subrect,
- dst_size,
- false,
- false)),
- pass1_shader_(scaler_impl->CreateYuvMrtShader(
- dst_size,
- gfx::Rect(0, 0, (dst_size.width() + 3) & ~3, dst_size.height()),
- gfx::Size((dst_size.width() + 3) / 4, dst_size.height()),
- flip_vertically,
- (swizzle == kSwizzleBGRA),
- GLHelperScaling::SHADER_YUV_MRT_PASS1)),
- pass2_shader_(scaler_impl->CreateYuvMrtShader(
- gfx::Size((dst_size.width() + 3) / 4, dst_size.height()),
- gfx::Rect(0,
- 0,
- (dst_size.width() + 7) / 8 * 2,
- dst_size.height()),
- gfx::Size((dst_size.width() + 7) / 8,
- (dst_size.height() + 1) / 2),
- false,
- (swizzle == kSwizzleBGRA),
- GLHelperScaling::SHADER_YUV_MRT_PASS2)),
- y_(gl, gfx::Size((dst_size.width() + 3) / 4, dst_size.height())),
- uv_(gl),
- u_(gl,
- gfx::Size((dst_size.width() + 7) / 8,
- (dst_size.height() + 1) / 2)),
- v_(gl,
- gfx::Size((dst_size.width() + 7) / 8,
- (dst_size.height() + 1) / 2)) {
- DCHECK(!(dst_size.width() & 1));
- DCHECK(!(dst_size.height() & 1));
-
- content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, uv_);
- gl->TexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- (dst_size.width() + 3) / 4,
- dst_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- NULL);
-}
-
-void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- const scoped_refptr<media::VideoFrame>& target,
- const gfx::Point& paste_location,
- const base::Callback<void(bool)>& callback) {
- DCHECK(!(paste_location.x() & 1));
- DCHECK(!(paste_location.y() & 1));
-
- GLuint mailbox_texture =
- copy_impl_->ConsumeMailboxToTexture(mailbox, sync_token);
-
- GLuint texture;
- if (quality_ == GLHelper::SCALER_QUALITY_FAST) {
- // Optimization: SCALER_QUALITY_FAST is just a single bilinear
- // pass, which pass1_shader_ can do just as well, so let's skip
- // the actual scaling in that case.
- texture = mailbox_texture;
- } else {
- // Scale texture to right size.
- scaler_.Scale(mailbox_texture);
- texture = scaler_.texture();
- }
-
- std::vector<GLuint> outputs(2);
- // Convert the scaled texture in to Y, U and V planes.
- outputs[0] = y_.texture();
- outputs[1] = uv_;
- pass1_shader_->Execute(texture, outputs);
-
- gl_->DeleteTextures(1, &mailbox_texture);
-
- outputs[0] = u_.texture();
- outputs[1] = v_.texture();
- pass2_shader_->Execute(uv_, outputs);
-
- const gfx::Rect paste_rect(paste_location, dst_size_);
- if (!target->visible_rect().Contains(paste_rect)) {
- LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!";
- callback.Run(false);
- return;
- }
-
- // Read back planes, one at a time.
- copy_impl_->ReadbackPlane(&y_,
- target,
- media::VideoFrame::kYPlane,
- 0,
- paste_rect,
- swizzle_,
- base::Bind(&nullcallback));
- copy_impl_->ReadbackPlane(&u_,
- target,
- media::VideoFrame::kUPlane,
- 1,
- paste_rect,
- swizzle_,
- base::Bind(&nullcallback));
- copy_impl_->ReadbackPlane(
- &v_,
- target,
- media::VideoFrame::kVPlane,
- 1,
- paste_rect,
- swizzle_,
- base::Bind(&CallbackKeepingVideoFrameAlive, target, callback));
- gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
- media::LetterboxYUV(target.get(), paste_rect);
-}
-
-bool GLHelper::IsReadbackConfigSupported(SkColorType color_type) {
- DCHECK(readback_support_.get());
- GLenum format, type;
- size_t bytes_per_pixel;
- FormatSupport support = readback_support_->GetReadbackConfig(
- color_type, false, &format, &type, &bytes_per_pixel);
-
- return (support == GLHelperReadbackSupport::SUPPORTED);
-}
-
-ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV(
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- bool use_mrt) {
- helper_->InitScalerImpl();
- // Just query if the best readback configuration needs a swizzle In
- // ReadbackPlane() we will choose GL_RGBA/GL_BGRA_EXT based on swizzle
- GLenum format, type;
- size_t bytes_per_pixel;
- FormatSupport supported = GetReadbackConfig(
- kRGBA_8888_SkColorType, true, &format, &type, &bytes_per_pixel);
- DCHECK((format == GL_RGBA || format == GL_BGRA_EXT) &&
- type == GL_UNSIGNED_BYTE);
-
- ReadbackSwizzle swizzle = kSwizzleNone;
- if (supported == GLHelperReadbackSupport::SWIZZLE)
- swizzle = kSwizzleBGRA;
-
- if (max_draw_buffers_ >= 2 && use_mrt) {
- return new ReadbackYUV_MRT(gl_,
- this,
- helper_->scaler_impl_.get(),
- quality,
- src_size,
- src_subrect,
- dst_size,
- flip_vertically,
- swizzle);
- }
- return new ReadbackYUVImpl(gl_,
- this,
- helper_->scaler_impl_.get(),
- quality,
- src_size,
- src_subrect,
- dst_size,
- flip_vertically,
- swizzle);
-}
-
-ReadbackYUVInterface* GLHelper::CreateReadbackPipelineYUV(
- ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- bool use_mrt) {
- InitCopyTextToImpl();
- return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality,
- src_size,
- src_subrect,
- dst_size,
- flip_vertically,
- use_mrt);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gl_helper.h b/chromium/content/common/gpu/client/gl_helper.h
deleted file mode 100644
index 2be3f5ae210..00000000000
--- a/chromium/content/common/gpu/client/gl_helper.h
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
-#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
-
-#include "base/atomicops.h"
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/common/content_export.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace gfx {
-class Point;
-class Rect;
-class Size;
-}
-
-namespace gpu {
-class ContextSupport;
-struct Mailbox;
-}
-
-namespace media {
-class VideoFrame;
-};
-
-class SkRegion;
-
-namespace content {
-
-class GLHelperScaling;
-
-class ScopedGLuint {
- public:
- typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids);
- typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n,
- const GLuint* ids);
- ScopedGLuint(gpu::gles2::GLES2Interface* gl,
- GenFunc gen_func,
- DeleteFunc delete_func)
- : gl_(gl), id_(0u), delete_func_(delete_func) {
- (gl_->*gen_func)(1, &id_);
- }
-
- operator GLuint() const { return id_; }
-
- GLuint id() const { return id_; }
-
- ~ScopedGLuint() {
- if (id_ != 0) {
- (gl_->*delete_func_)(1, &id_);
- }
- }
-
- private:
- gpu::gles2::GLES2Interface* gl_;
- GLuint id_;
- DeleteFunc delete_func_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedGLuint);
-};
-
-class ScopedBuffer : public ScopedGLuint {
- public:
- explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl)
- : ScopedGLuint(gl,
- &gpu::gles2::GLES2Interface::GenBuffers,
- &gpu::gles2::GLES2Interface::DeleteBuffers) {}
-};
-
-class ScopedFramebuffer : public ScopedGLuint {
- public:
- explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl)
- : ScopedGLuint(gl,
- &gpu::gles2::GLES2Interface::GenFramebuffers,
- &gpu::gles2::GLES2Interface::DeleteFramebuffers) {}
-};
-
-class ScopedTexture : public ScopedGLuint {
- public:
- explicit ScopedTexture(gpu::gles2::GLES2Interface* gl)
- : ScopedGLuint(gl,
- &gpu::gles2::GLES2Interface::GenTextures,
- &gpu::gles2::GLES2Interface::DeleteTextures) {}
-};
-
-template <GLenum Target>
-class ScopedBinder {
- public:
- typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target,
- GLuint id);
- ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func)
- : gl_(gl), bind_func_(bind_func) {
- (gl_->*bind_func_)(Target, id);
- }
-
- virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); }
-
- private:
- gpu::gles2::GLES2Interface* gl_;
- BindFunc bind_func_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
-};
-
-template <GLenum Target>
-class ScopedBufferBinder : ScopedBinder<Target> {
- public:
- ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
- : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {}
-};
-
-template <GLenum Target>
-class ScopedFramebufferBinder : ScopedBinder<Target> {
- public:
- ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
- : ScopedBinder<Target>(gl,
- id,
- &gpu::gles2::GLES2Interface::BindFramebuffer) {}
-};
-
-template <GLenum Target>
-class ScopedTextureBinder : ScopedBinder<Target> {
- public:
- ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
- : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) {
- }
-};
-
-class ReadbackYUVInterface;
-class GLHelperReadbackSupport;
-
-// Provides higher level operations on top of the gpu::gles2::GLES2Interface
-// interfaces.
-class CONTENT_EXPORT GLHelper {
- public:
- GLHelper(gpu::gles2::GLES2Interface* gl,
- gpu::ContextSupport* context_support);
- ~GLHelper();
-
- enum ScalerQuality {
- // Bilinear single pass, fastest possible.
- SCALER_QUALITY_FAST = 1,
-
- // Bilinear upscale + N * 50% bilinear downscales.
- // This is still fast enough for most purposes and
- // Image quality is nearly as good as the BEST option.
- SCALER_QUALITY_GOOD = 2,
-
- // Bicubic upscale + N * 50% bicubic downscales.
- // Produces very good quality scaled images, but it's
- // 2-8x slower than the "GOOD" quality, so it's not always
- // worth it.
- SCALER_QUALITY_BEST = 3,
- };
-
- // Copies the block of pixels specified with |src_subrect| from |src_texture|,
- // scales it to |dst_size|, and writes it into |out|.
- // |src_size| is the size of |src_texture|. The result is in |out_color_type|
- // format and is potentially flipped vertically to make it a correct image
- // representation. |callback| is invoked with the copy result when the copy
- // operation has completed.
- // Note that the src_texture will have the min/mag filter set to GL_LINEAR
- // and wrap_s/t set to CLAMP_TO_EDGE in this call.
- void CropScaleReadbackAndCleanTexture(
- GLuint src_texture,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality);
-
- // Copies the block of pixels specified with |src_subrect| from |src_mailbox|,
- // scales it to |dst_size|, and writes it into |out|.
- // |src_size| is the size of |src_mailbox|. The result is in |out_color_type|
- // format and is potentially flipped vertically to make it a correct image
- // representation. |callback| is invoked with the copy result when the copy
- // operation has completed.
- // Note that the texture bound to src_mailbox will have the min/mag filter set
- // to GL_LINEAR and wrap_s/t set to CLAMP_TO_EDGE in this call. src_mailbox is
- // assumed to be GL_TEXTURE_2D.
- void CropScaleReadbackAndCleanMailbox(
- const gpu::Mailbox& src_mailbox,
- const gpu::SyncToken& sync_token,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- unsigned char* out,
- const SkColorType out_color_type,
- const base::Callback<void(bool)>& callback,
- GLHelper::ScalerQuality quality);
-
- // Copies the texture data out of |texture| into |out|. |size| is the
- // size of the texture. No post processing is applied to the pixels. The
- // texture is assumed to have a format of GL_RGBA with a pixel type of
- // GL_UNSIGNED_BYTE. This is a blocking call that calls glReadPixels on the
- // current OpenGL context.
- void ReadbackTextureSync(GLuint texture,
- const gfx::Rect& src_rect,
- unsigned char* out,
- SkColorType format);
-
- void ReadbackTextureAsync(GLuint texture,
- const gfx::Size& dst_size,
- unsigned char* out,
- SkColorType color_type,
- const base::Callback<void(bool)>& callback);
-
- // Creates a copy of the specified texture. |size| is the size of the texture.
- // Note that the src_texture will have the min/mag filter set to GL_LINEAR
- // and wrap_s/t set to CLAMP_TO_EDGE in this call.
- GLuint CopyTexture(GLuint texture, const gfx::Size& size);
-
- // Creates a scaled copy of the specified texture. |src_size| is the size of
- // the texture and |dst_size| is the size of the resulting copy.
- // Note that the src_texture will have the min/mag filter set to GL_LINEAR
- // and wrap_s/t set to CLAMP_TO_EDGE in this call.
- GLuint CopyAndScaleTexture(GLuint texture,
- const gfx::Size& src_size,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- ScalerQuality quality);
-
- // Returns the shader compiled from the source.
- GLuint CompileShaderFromSource(const GLchar* source, GLenum type);
-
- // Copies all pixels from |previous_texture| into |texture| that are
- // inside the region covered by |old_damage| but not part of |new_damage|.
- void CopySubBufferDamage(GLenum target,
- GLuint texture,
- GLuint previous_texture,
- const SkRegion& new_damage,
- const SkRegion& old_damage);
-
- // Simply creates a texture.
- GLuint CreateTexture();
- // Deletes a texture.
- void DeleteTexture(GLuint texture_id);
-
- // Inserts a fence sync, flushes, and generates a sync token.
- void GenerateSyncToken(gpu::SyncToken* sync_token);
-
- // Wait for the sync token before executing further GL commands.
- void WaitSyncToken(const gpu::SyncToken& sync_token);
-
- // Creates a mailbox holder that is attached to the given texture id, with a
- // sync point to wait on before using the mailbox. Returns a holder with an
- // empty mailbox on failure.
- // Note the texture is assumed to be GL_TEXTURE_2D.
- gpu::MailboxHolder ProduceMailboxHolderFromTexture(GLuint texture_id);
-
- // Creates a texture and consumes a mailbox into it. Returns 0 on failure.
- // Note the mailbox is assumed to be GL_TEXTURE_2D.
- GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token);
-
- // Resizes the texture's size to |size|.
- void ResizeTexture(GLuint texture, const gfx::Size& size);
-
- // Copies the framebuffer data given in |rect| to |texture|.
- void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect);
-
- // Copies the all framebuffer data to |texture|. |size| specifies the
- // size of the framebuffer.
- void CopyTextureFullImage(GLuint texture, const gfx::Size& size);
-
- // Flushes GL commands.
- void Flush();
-
- // Force commands in the current command buffer to be executed before commands
- // in other command buffers from the same process (ie channel to the GPU
- // process).
- void InsertOrderingBarrier();
-
- // A scaler will cache all intermediate textures and programs
- // needed to scale from a specified size to a destination size.
- // If the source or destination sizes changes, you must create
- // a new scaler.
- class CONTENT_EXPORT ScalerInterface {
- public:
- ScalerInterface() {}
- virtual ~ScalerInterface() {}
-
- // Note that the src_texture will have the min/mag filter set to GL_LINEAR
- // and wrap_s/t set to CLAMP_TO_EDGE in this call.
- virtual void Scale(GLuint source_texture, GLuint dest_texture) = 0;
- virtual const gfx::Size& SrcSize() = 0;
- virtual const gfx::Rect& SrcSubrect() = 0;
- virtual const gfx::Size& DstSize() = 0;
- };
-
- // Note that the quality may be adjusted down if texture
- // allocations fail or hardware doesn't support the requtested
- // quality. Note that ScalerQuality enum is arranged in
- // numerical order for simplicity.
- ScalerInterface* CreateScaler(ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle);
-
- // Create a readback pipeline that will scale a subsection of the source
- // texture, then convert it to YUV422 planar form and then read back that.
- // This reduces the amount of memory read from GPU to CPU memory by a factor
- // 2.6, which can be quite handy since readbacks have very limited speed
- // on some platforms. All values in |dst_size| must be a multiple of two. If
- // |use_mrt| is true, the pipeline will try to optimize the YUV conversion
- // using the multi-render-target extension. |use_mrt| should only be set to
- // false for testing.
- ReadbackYUVInterface* CreateReadbackPipelineYUV(ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool flip_vertically,
- bool use_mrt);
-
- // Returns the maximum number of draw buffers available,
- // 0 if GL_EXT_draw_buffers is not available.
- GLint MaxDrawBuffers();
-
- // Checks whether the readbback is supported for texture with the
- // matching config. This doesnt check for cross format readbacks.
- bool IsReadbackConfigSupported(SkColorType texture_format);
-
- protected:
- class CopyTextureToImpl;
-
- // Creates |copy_texture_to_impl_| if NULL.
- void InitCopyTextToImpl();
- // Creates |scaler_impl_| if NULL.
- void InitScalerImpl();
-
- enum ReadbackSwizzle {
- kSwizzleNone = 0,
- kSwizzleBGRA
- };
-
- gpu::gles2::GLES2Interface* gl_;
- gpu::ContextSupport* context_support_;
- scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_;
- scoped_ptr<GLHelperScaling> scaler_impl_;
- scoped_ptr<GLHelperReadbackSupport> readback_support_;
-
- DISALLOW_COPY_AND_ASSIGN(GLHelper);
-};
-
-// Similar to a ScalerInterface, a yuv readback pipeline will
-// cache a scaler and all intermediate textures and frame buffers
-// needed to scale, crop, letterbox and read back a texture from
-// the GPU into CPU-accessible RAM. A single readback pipeline
-// can handle multiple outstanding readbacks at the same time, but
-// if the source or destination sizes change, you'll need to create
-// a new readback pipeline.
-class CONTENT_EXPORT ReadbackYUVInterface {
- public:
- ReadbackYUVInterface() {}
- virtual ~ReadbackYUVInterface() {}
-
- // Note that |target| must use YV12 format. |paste_location| specifies where
- // the captured pixels that are read back will be placed in the video frame.
- // The region defined by the |paste_location| and the |dst_size| specified in
- // the call to CreateReadbackPipelineYUV() must be fully contained within
- // |target->visible_rect()|.
- virtual void ReadbackYUV(const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- const scoped_refptr<media::VideoFrame>& target,
- const gfx::Point& paste_location,
- const base::Callback<void(bool)>& callback) = 0;
- virtual GLHelper::ScalerInterface* scaler() = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
diff --git a/chromium/content/common/gpu/client/gl_helper_benchmark.cc b/chromium/content/common/gpu/client/gl_helper_benchmark.cc
deleted file mode 100644
index 9e751b37852..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_benchmark.cc
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2012 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.
-
-// This file looks like a unit test, but it contains benchmarks and test
-// utilities intended for manual evaluation of the scalers in
-// gl_helper*. These tests produce output in the form of files and printouts,
-// but cannot really "fail". There is no point in making these tests part
-// of any test automation run.
-
-#include <stddef.h>
-#include <stdio.h>
-#include <cmath>
-#include <string>
-#include <vector>
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES2/gl2extchromium.h>
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/gl_helper.h"
-#include "content/common/gpu/client/gl_helper_scaling.h"
-#include "content/public/test/unittest_test_suite.h"
-#include "content/test/content_test_suite.h"
-#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkTypes.h"
-#include "ui/gfx/codec/png_codec.h"
-#include "ui/gl/gl_surface.h"
-
-#if defined(OS_MACOSX)
-#include "base/mac/scoped_nsautorelease_pool.h"
-#endif
-
-namespace content {
-
-using blink::WebGLId;
-using blink::WebGraphicsContext3D;
-
-content::GLHelper::ScalerQuality kQualities[] = {
- content::GLHelper::SCALER_QUALITY_BEST,
- content::GLHelper::SCALER_QUALITY_GOOD,
- content::GLHelper::SCALER_QUALITY_FAST,
-};
-
-const char *kQualityNames[] = {
- "best",
- "good",
- "fast",
-};
-
-class GLHelperTest : public testing::Test {
- protected:
- void SetUp() override {
- WebGraphicsContext3D::Attributes attributes;
- bool lose_context_when_out_of_memory = false;
- context_ = gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl::
- CreateOffscreenContext(attributes, lose_context_when_out_of_memory);
- context_->InitializeOnCurrentThread();
-
- helper_.reset(
- new content::GLHelper(context_->GetGLInterface(),
- context_->GetContextSupport()));
- helper_scaling_.reset(new content::GLHelperScaling(
- context_->GetGLInterface(),
- helper_.get()));
- }
-
- void TearDown() override {
- helper_scaling_.reset(NULL);
- helper_.reset(NULL);
- context_.reset(NULL);
- }
-
-
- void LoadPngFileToSkBitmap(const base::FilePath& filename,
- SkBitmap* bitmap) {
- std::string compressed;
- base::ReadFileToString(base::MakeAbsoluteFilePath(filename), &compressed);
- ASSERT_TRUE(compressed.size());
- ASSERT_TRUE(gfx::PNGCodec::Decode(
- reinterpret_cast<const unsigned char*>(compressed.data()),
- compressed.size(), bitmap));
- }
-
- // Save the image to a png file. Used to create the initial test files.
- void SaveToFile(SkBitmap* bitmap, const base::FilePath& filename) {
- std::vector<unsigned char> compressed;
- ASSERT_TRUE(gfx::PNGCodec::Encode(
- static_cast<unsigned char*>(bitmap->getPixels()),
- gfx::PNGCodec::FORMAT_BGRA,
- gfx::Size(bitmap->width(), bitmap->height()),
- static_cast<int>(bitmap->rowBytes()),
- true,
- std::vector<gfx::PNGCodec::Comment>(),
- &compressed));
- ASSERT_TRUE(compressed.size());
- FILE* f = base::OpenFile(filename, "wb");
- ASSERT_TRUE(f);
- ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f),
- compressed.size());
- base::CloseFile(f);
- }
-
- scoped_ptr<gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl>
- context_;
- scoped_ptr<content::GLHelper> helper_;
- scoped_ptr<content::GLHelperScaling> helper_scaling_;
- std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_;
-};
-
-
-TEST_F(GLHelperTest, ScaleBenchmark) {
- int output_sizes[] = { 1920, 1080,
- 1249, 720, // Output size on pixel
- 256, 144 };
- int input_sizes[] = { 3200, 2040,
- 2560, 1476, // Pixel tab size
- 1920, 1080,
- 1280, 720,
- 800, 480,
- 256, 144 };
-
- for (size_t q = 0; q < arraysize(kQualities); q++) {
- for (size_t outsize = 0;
- outsize < arraysize(output_sizes);
- outsize += 2) {
- for (size_t insize = 0;
- insize < arraysize(input_sizes);
- insize += 2) {
- WebGLId src_texture = context_->createTexture();
- WebGLId dst_texture = context_->createTexture();
- WebGLId framebuffer = context_->createFramebuffer();
- const gfx::Size src_size(input_sizes[insize],
- input_sizes[insize + 1]);
- const gfx::Size dst_size(output_sizes[outsize],
- output_sizes[outsize + 1]);
- SkBitmap input;
- input.allocN32Pixels(src_size.width(), src_size.height());
-
- SkBitmap output_pixels;
- output_pixels.allocN32Pixels(dst_size.width(), dst_size.height());
-
- context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
- context_->bindTexture(GL_TEXTURE_2D, dst_texture);
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- dst_size.width(),
- dst_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- 0);
- context_->bindTexture(GL_TEXTURE_2D, src_texture);
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- src_size.width(),
- src_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- input.getPixels());
-
- gfx::Rect src_subrect(0, 0,
- src_size.width(), src_size.height());
- scoped_ptr<content::GLHelper::ScalerInterface> scaler(
- helper_->CreateScaler(kQualities[q],
- src_size,
- src_subrect,
- dst_size,
- false,
- false));
- // Scale once beforehand before we start measuring.
- scaler->Scale(src_texture, dst_texture);
- context_->finish();
-
- base::TimeTicks start_time = base::TimeTicks::Now();
- int iterations = 0;
- base::TimeTicks end_time;
- while (true) {
- for (int i = 0; i < 50; i++) {
- iterations++;
- scaler->Scale(src_texture, dst_texture);
- context_->flush();
- }
- context_->finish();
- end_time = base::TimeTicks::Now();
- if (iterations > 2000) {
- break;
- }
- if ((end_time - start_time).InMillisecondsF() > 1000) {
- break;
- }
- }
- context_->deleteTexture(dst_texture);
- context_->deleteTexture(src_texture);
- context_->deleteFramebuffer(framebuffer);
-
- std::string name;
- name = base::StringPrintf("scale_%dx%d_to_%dx%d_%s",
- src_size.width(),
- src_size.height(),
- dst_size.width(),
- dst_size.height(),
- kQualityNames[q]);
-
- float ms = (end_time - start_time).InMillisecondsF() / iterations;
- printf("*RESULT gpu_scale_time: %s=%.2f ms\n", name.c_str(), ms);
- }
- }
- }
-}
-
-// This is more of a test utility than a test.
-// Put an PNG image called "testimage.png" in your
-// current directory, then run this test. It will
-// create testoutput_Q_P.png, where Q is the scaling
-// mode and P is the scaling percentage taken from
-// the table below.
-TEST_F(GLHelperTest, DISABLED_ScaleTestImage) {
- int percents[] = {
- 230,
- 180,
- 150,
- 110,
- 90,
- 70,
- 50,
- 49,
- 40,
- 20,
- 10,
- };
-
- SkBitmap input;
- LoadPngFileToSkBitmap(base::FilePath(
- FILE_PATH_LITERAL("testimage.png")), &input);
-
- WebGLId framebuffer = context_->createFramebuffer();
- WebGLId src_texture = context_->createTexture();
- const gfx::Size src_size(input.width(), input.height());
- context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
- context_->bindTexture(GL_TEXTURE_2D, src_texture);
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- src_size.width(),
- src_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- input.getPixels());
-
- for (size_t q = 0; q < arraysize(kQualities); q++) {
- for (size_t p = 0; p < arraysize(percents); p++) {
- const gfx::Size dst_size(input.width() * percents[p] / 100,
- input.height() * percents[p] / 100);
- WebGLId dst_texture = helper_->CopyAndScaleTexture(
- src_texture,
- src_size,
- dst_size,
- false,
- kQualities[q]);
-
- SkBitmap output_pixels;
- output_pixels.allocN32Pixels(dst_size.width(), dst_size.height());
-
- helper_->ReadbackTextureSync(
- dst_texture,
- gfx::Rect(0, 0,
- dst_size.width(),
- dst_size.height()),
- static_cast<unsigned char *>(output_pixels.getPixels()),
- kN32_SkColorType);
- context_->deleteTexture(dst_texture);
- std::string filename = base::StringPrintf("testoutput_%s_%d.ppm",
- kQualityNames[q],
- percents[p]);
- VLOG(0) << "Writing " << filename;
- SaveToFile(&output_pixels, base::FilePath::FromUTF8Unsafe(filename));
- }
- }
- context_->deleteTexture(src_texture);
- context_->deleteFramebuffer(framebuffer);
-}
-
-} // namespace
-
-// These tests needs to run against a proper GL environment, so we
-// need to set it up before we can run the tests.
-int main(int argc, char** argv) {
- base::CommandLine::Init(argc, argv);
- base::TestSuite* suite = new content::ContentTestSuite(argc, argv);
-#if defined(OS_MACOSX)
- base::mac::ScopedNSAutoreleasePool pool;
-#endif
- gfx::GLSurface::InitializeOneOff();
-
- return content::UnitTestTestSuite(suite).Run();
-}
diff --git a/chromium/content/common/gpu/client/gl_helper_readback_support.cc b/chromium/content/common/gpu/client/gl_helper_readback_support.cc
deleted file mode 100644
index e773ca90782..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_readback_support.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/client/gl_helper_readback_support.h"
-#include "base/logging.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
-
-namespace content {
-
-GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl)
- : gl_(gl) {
- InitializeReadbackSupport();
-}
-
-GLHelperReadbackSupport::~GLHelperReadbackSupport() {}
-
-void GLHelperReadbackSupport::InitializeReadbackSupport() {
- // We are concerned about 16, 32-bit formats only. The below are the most
- // used 16, 32-bit formats. In future if any new format support is needed
- // that should be added here. Initialize the array with
- // GLHelperReadbackSupport::NOT_SUPPORTED as we dont know the supported
- // formats yet.
- for (int i = 0; i <= kLastEnum_SkColorType; ++i) {
- format_support_table_[i] = GLHelperReadbackSupport::NOT_SUPPORTED;
- }
- // TODO(sikugu): kAlpha_8_SkColorType support check is failing on mesa.
- // See crbug.com/415667.
- CheckForReadbackSupport(kRGB_565_SkColorType);
- CheckForReadbackSupport(kARGB_4444_SkColorType);
- CheckForReadbackSupport(kRGBA_8888_SkColorType);
- CheckForReadbackSupport(kBGRA_8888_SkColorType);
- // Further any formats, support should be checked here.
-}
-
-void GLHelperReadbackSupport::CheckForReadbackSupport(
- SkColorType texture_format) {
- bool supports_format = false;
- switch (texture_format) {
- case kRGB_565_SkColorType:
- supports_format = SupportsFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
- break;
- case kRGBA_8888_SkColorType:
- // This is the baseline, assume always true.
- supports_format = true;
- break;
- case kBGRA_8888_SkColorType:
- supports_format = SupportsFormat(GL_BGRA_EXT, GL_UNSIGNED_BYTE);
- break;
- case kARGB_4444_SkColorType:
- supports_format = false;
- break;
- default:
- NOTREACHED();
- supports_format = false;
- break;
- }
- DCHECK((int)texture_format <= (int)kLastEnum_SkColorType);
- format_support_table_[texture_format] =
- supports_format ? GLHelperReadbackSupport::SUPPORTED
- : GLHelperReadbackSupport::NOT_SUPPORTED;
-}
-
-void GLHelperReadbackSupport::GetAdditionalFormat(GLenum format,
- GLenum type,
- GLenum* format_out,
- GLenum* type_out) {
- for (unsigned int i = 0; i < format_cache_.size(); i++) {
- if (format_cache_[i].format == format && format_cache_[i].type == type) {
- *format_out = format_cache_[i].read_format;
- *type_out = format_cache_[i].read_type;
- return;
- }
- }
-
- const int kTestSize = 64;
- content::ScopedTexture dst_texture(gl_);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl_->TexImage2D(
- GL_TEXTURE_2D, 0, format, kTestSize, kTestSize, 0, format, type, NULL);
- ScopedFramebuffer dst_framebuffer(gl_);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
- dst_framebuffer);
- gl_->FramebufferTexture2D(
- GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_texture, 0);
- GLint format_tmp = 0, type_tmp = 0;
- gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format_tmp);
- gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type_tmp);
- *format_out = format_tmp;
- *type_out = type_tmp;
-
- struct FormatCacheEntry entry = { format, type, *format_out, *type_out };
- format_cache_.push_back(entry);
-}
-
-bool GLHelperReadbackSupport::SupportsFormat(GLenum format, GLenum type) {
- // GLES2.0 Specification says this pairing is always supported
- // with additional format from GL_IMPLEMENTATION_COLOR_READ_FORMAT/TYPE
- if (format == GL_RGBA && type == GL_UNSIGNED_BYTE)
- return true;
-
- if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
- const GLubyte* tmp = gl_->GetString(GL_EXTENSIONS);
- if (tmp) {
- std::string extensions =
- " " + std::string(reinterpret_cast<const char*>(tmp)) + " ";
- if (extensions.find(" GL_EXT_read_format_bgra ") != std::string::npos) {
- return true;
- }
- }
- }
-
- bool supports_format = false;
- GLenum ext_format = 0, ext_type = 0;
- GetAdditionalFormat(format, type, &ext_format, &ext_type);
- if ((ext_format == format) && (ext_type == type)) {
- supports_format = true;
- }
- return supports_format;
-}
-
-GLHelperReadbackSupport::FormatSupport
-GLHelperReadbackSupport::GetReadbackConfig(SkColorType color_type,
- bool can_swizzle,
- GLenum* format,
- GLenum* type,
- size_t* bytes_per_pixel) {
- DCHECK(format && type && bytes_per_pixel);
- *bytes_per_pixel = 4;
- *type = GL_UNSIGNED_BYTE;
- GLenum new_format = 0, new_type = 0;
- switch (color_type) {
- case kRGB_565_SkColorType:
- if (format_support_table_[color_type] ==
- GLHelperReadbackSupport::SUPPORTED) {
- *format = GL_RGB;
- *type = GL_UNSIGNED_SHORT_5_6_5;
- *bytes_per_pixel = 2;
- return GLHelperReadbackSupport::SUPPORTED;
- }
- break;
- case kRGBA_8888_SkColorType:
- *format = GL_RGBA;
- if (can_swizzle) {
- // If GL_BGRA_EXT is advertised as the readback format through
- // GL_IMPLEMENTATION_COLOR_READ_FORMAT then assume it is preferred by
- // the implementation for performance.
- GetAdditionalFormat(*format, *type, &new_format, &new_type);
-
- if (new_format == GL_BGRA_EXT && new_type == GL_UNSIGNED_BYTE) {
- *format = GL_BGRA_EXT;
- return GLHelperReadbackSupport::SWIZZLE;
- }
- }
- return GLHelperReadbackSupport::SUPPORTED;
- case kBGRA_8888_SkColorType:
- *format = GL_BGRA_EXT;
- if (format_support_table_[color_type] ==
- GLHelperReadbackSupport::SUPPORTED)
- return GLHelperReadbackSupport::SUPPORTED;
-
- if (can_swizzle) {
- *format = GL_RGBA;
- return GLHelperReadbackSupport::SWIZZLE;
- }
-
- break;
- case kARGB_4444_SkColorType:
- return GLHelperReadbackSupport::NOT_SUPPORTED;
- default:
- NOTREACHED();
- break;
- }
-
- return GLHelperReadbackSupport::NOT_SUPPORTED;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gl_helper_readback_support.h b/chromium/content/common/gpu/client/gl_helper_readback_support.h
deleted file mode 100644
index f9329e9912c..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_readback_support.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_CLIENT_GL_HELPER_READBACK_SUPPORT_H_
-#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_READBACK_SUPPORT_H_
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "content/common/gpu/client/gl_helper.h"
-
-namespace content {
-
-class CONTENT_EXPORT GLHelperReadbackSupport {
- public:
- enum FormatSupport { SUPPORTED, SWIZZLE, NOT_SUPPORTED };
-
- GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl);
-
- ~GLHelperReadbackSupport();
-
- // For a given color type retrieve whether readback is supported and if so
- // how it should be performed. The |format|, |type| and |bytes_per_pixel| are
- // the values that should be used with glReadPixels to facilitate the
- // readback. If |can_swizzle| is true then this method will return SWIZZLE if
- // the data needs to be swizzled before using the returned |format| otherwise
- // the method will return SUPPORTED to indicate that readback is permitted of
- // this color othewise NOT_SUPPORTED will be returned. This method always
- // overwrites the out values irrespective of the return value.
- FormatSupport GetReadbackConfig(SkColorType color_type,
- bool can_swizzle,
- GLenum* format,
- GLenum* type,
- size_t* bytes_per_pixel);
- // Provides the additional readback format/type pairing for a render target
- // of a given format/type pairing
- void GetAdditionalFormat(GLenum format, GLenum type, GLenum *format_out,
- GLenum *type_out);
- private:
- struct FormatCacheEntry {
- GLenum format;
- GLenum type;
- GLenum read_format;
- GLenum read_type;
- };
-
- // This populates the format_support_table with the list of supported
- // formats.
- void InitializeReadbackSupport();
-
- // This api is called once per format and it is done in the
- // InitializeReadbackSupport. We should not use this any where
- // except the InitializeReadbackSupport.Calling this at other places
- // can distrub the state of normal gl operations.
- void CheckForReadbackSupport(SkColorType texture_format);
-
- // Helper functions for checking the supported texture formats.
- // Avoid using this API in between texture operations, as this does some
- // teture opertions (bind, attach) internally.
- bool SupportsFormat(GLenum format, GLenum type);
-
- FormatSupport format_support_table_[kLastEnum_SkColorType + 1];
-
- gpu::gles2::GLES2Interface* gl_;
- std::vector<struct FormatCacheEntry> format_cache_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_READBACK_SUPPORT_H_
diff --git a/chromium/content/common/gpu/client/gl_helper_scaling.cc b/chromium/content/common/gpu/client/gl_helper_scaling.cc
deleted file mode 100644
index f4cd6b3eb52..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_scaling.cc
+++ /dev/null
@@ -1,934 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/client/gl_helper_scaling.h"
-
-#include <stddef.h>
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace content {
-
-GLHelperScaling::GLHelperScaling(GLES2Interface* gl, GLHelper* helper)
- : gl_(gl), helper_(helper), vertex_attributes_buffer_(gl_) {
- InitBuffer();
-}
-
-GLHelperScaling::~GLHelperScaling() {}
-
-// Used to keep track of a generated shader program. The program
-// is passed in as text through Setup and is used by calling
-// UseProgram() with the right parameters. Note that |gl_|
-// and |helper_| are assumed to live longer than this program.
-class ShaderProgram : public base::RefCounted<ShaderProgram> {
- public:
- ShaderProgram(GLES2Interface* gl, GLHelper* helper)
- : gl_(gl),
- helper_(helper),
- program_(gl_->CreateProgram()),
- position_location_(-1),
- texcoord_location_(-1),
- src_subrect_location_(-1),
- src_pixelsize_location_(-1),
- dst_pixelsize_location_(-1),
- scaling_vector_location_(-1),
- color_weights_location_(-1) {}
-
- // Compile shader program.
- void Setup(const GLchar* vertex_shader_text,
- const GLchar* fragment_shader_text);
-
- // UseProgram must be called with GL_TEXTURE_2D bound to the
- // source texture and GL_ARRAY_BUFFER bound to a vertex
- // attribute buffer.
- void UseProgram(const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool scale_x,
- bool flip_y,
- GLfloat color_weights[4]);
-
- bool Initialized() const { return position_location_ != -1; }
-
- private:
- friend class base::RefCounted<ShaderProgram>;
- ~ShaderProgram() { gl_->DeleteProgram(program_); }
-
- GLES2Interface* gl_;
- GLHelper* helper_;
-
- // A program for copying a source texture into a destination texture.
- GLuint program_;
-
- // The location of the position in the program.
- GLint position_location_;
- // The location of the texture coordinate in the program.
- GLint texcoord_location_;
- // The location of the source texture in the program.
- GLint texture_location_;
- // The location of the texture coordinate of
- // the sub-rectangle in the program.
- GLint src_subrect_location_;
- // Location of size of source image in pixels.
- GLint src_pixelsize_location_;
- // Location of size of destination image in pixels.
- GLint dst_pixelsize_location_;
- // Location of vector for scaling direction.
- GLint scaling_vector_location_;
- // Location of color weights.
- GLint color_weights_location_;
-
- DISALLOW_COPY_AND_ASSIGN(ShaderProgram);
-};
-
-// Implementation of a single stage in a scaler pipeline. If the pipeline has
-// multiple stages, it calls Scale() on the subscaler, then further scales the
-// output. Caches textures and framebuffers to avoid allocating/deleting
-// them once per frame, which can be expensive on some drivers.
-class ScalerImpl : public GLHelper::ScalerInterface,
- public GLHelperScaling::ShaderInterface {
- public:
- // |gl| and |copy_impl| are expected to live longer than this object.
- // |src_size| is the size of the input texture in pixels.
- // |dst_size| is the size of the output texutre in pixels.
- // |src_subrect| is the portion of the src to copy to the output texture.
- // If |scale_x| is true, we are scaling along the X axis, otherwise Y.
- // If we are scaling in both X and Y, |scale_x| is ignored.
- // If |vertically_flip_texture| is true, output will be upside-down.
- // If |swizzle| is true, RGBA will be transformed into BGRA.
- // |color_weights| are only used together with SHADER_PLANAR to specify
- // how to convert RGB colors into a single value.
- ScalerImpl(GLES2Interface* gl,
- GLHelperScaling* scaler_helper,
- const GLHelperScaling::ScalerStage& scaler_stage,
- ScalerImpl* subscaler,
- const float* color_weights)
- : gl_(gl),
- scaler_helper_(scaler_helper),
- spec_(scaler_stage),
- intermediate_texture_(0),
- dst_framebuffer_(gl),
- subscaler_(subscaler) {
- if (color_weights) {
- color_weights_[0] = color_weights[0];
- color_weights_[1] = color_weights[1];
- color_weights_[2] = color_weights[2];
- color_weights_[3] = color_weights[3];
- } else {
- color_weights_[0] = 0.0;
- color_weights_[1] = 0.0;
- color_weights_[2] = 0.0;
- color_weights_[3] = 0.0;
- }
- shader_program_ =
- scaler_helper_->GetShaderProgram(spec_.shader, spec_.swizzle);
-
- if (subscaler_) {
- intermediate_texture_ = 0u;
- gl_->GenTextures(1, &intermediate_texture_);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_,
- intermediate_texture_);
- gl_->TexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- spec_.src_size.width(),
- spec_.src_size.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- NULL);
- }
- }
-
- ~ScalerImpl() override {
- if (intermediate_texture_) {
- gl_->DeleteTextures(1, &intermediate_texture_);
- }
- }
-
- // GLHelperShader::ShaderInterface implementation.
- void Execute(GLuint source_texture,
- const std::vector<GLuint>& dest_textures) override {
- if (subscaler_) {
- subscaler_->Scale(source_texture, intermediate_texture_);
- source_texture = intermediate_texture_;
- }
-
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- gl_, dst_framebuffer_);
- DCHECK_GT(dest_textures.size(), 0U);
- scoped_ptr<GLenum[]> buffers(new GLenum[dest_textures.size()]);
- for (size_t t = 0; t < dest_textures.size(); t++) {
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dest_textures[t]);
- gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0 + t,
- GL_TEXTURE_2D,
- dest_textures[t],
- 0);
- buffers[t] = GL_COLOR_ATTACHMENT0 + t;
- }
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, source_texture);
-
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
- gl_, scaler_helper_->vertex_attributes_buffer_);
- shader_program_->UseProgram(spec_.src_size,
- spec_.src_subrect,
- spec_.dst_size,
- spec_.scale_x,
- spec_.vertically_flip_texture,
- color_weights_);
- gl_->Viewport(0, 0, spec_.dst_size.width(), spec_.dst_size.height());
-
- if (dest_textures.size() > 1) {
- DCHECK_LE(static_cast<int>(dest_textures.size()),
- scaler_helper_->helper_->MaxDrawBuffers());
- gl_->DrawBuffersEXT(dest_textures.size(), buffers.get());
- }
- // Conduct texture mapping by drawing a quad composed of two triangles.
- gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- if (dest_textures.size() > 1) {
- // Set the draw buffers back to not confuse others.
- gl_->DrawBuffersEXT(1, &buffers[0]);
- }
- }
-
- // GLHelper::ScalerInterface implementation.
- void Scale(GLuint source_texture, GLuint dest_texture) override {
- std::vector<GLuint> tmp(1);
- tmp[0] = dest_texture;
- Execute(source_texture, tmp);
- }
-
- const gfx::Size& SrcSize() override {
- if (subscaler_) {
- return subscaler_->SrcSize();
- }
- return spec_.src_size;
- }
- const gfx::Rect& SrcSubrect() override {
- if (subscaler_) {
- return subscaler_->SrcSubrect();
- }
- return spec_.src_subrect;
- }
- const gfx::Size& DstSize() override { return spec_.dst_size; }
-
- private:
- GLES2Interface* gl_;
- GLHelperScaling* scaler_helper_;
- GLHelperScaling::ScalerStage spec_;
- GLfloat color_weights_[4];
- GLuint intermediate_texture_;
- scoped_refptr<ShaderProgram> shader_program_;
- ScopedFramebuffer dst_framebuffer_;
- scoped_ptr<ScalerImpl> subscaler_;
-};
-
-GLHelperScaling::ScalerStage::ScalerStage(ShaderType shader_,
- gfx::Size src_size_,
- gfx::Rect src_subrect_,
- gfx::Size dst_size_,
- bool scale_x_,
- bool vertically_flip_texture_,
- bool swizzle_)
- : shader(shader_),
- src_size(src_size_),
- src_subrect(src_subrect_),
- dst_size(dst_size_),
- scale_x(scale_x_),
- vertically_flip_texture(vertically_flip_texture_),
- swizzle(swizzle_) {}
-
-// The important inputs for this function is |x_ops| and
-// |y_ops|. They represent scaling operations to be done
-// on an imag of size |src_size|. If |quality| is SCALER_QUALITY_BEST,
-// then we will interpret these scale operations literally and we'll
-// create one scaler stage for each ScaleOp. However, if |quality|
-// is SCALER_QUALITY_GOOD, then we can do a whole bunch of optimizations
-// by combining two or more ScaleOps in to a single scaler stage.
-// Normally we process ScaleOps from |y_ops| first and |x_ops| after
-// all |y_ops| are processed, but sometimes we can combine one or more
-// operation from both queues essentially for free. This is the reason
-// why |x_ops| and |y_ops| aren't just one single queue.
-void GLHelperScaling::ConvertScalerOpsToScalerStages(
- GLHelper::ScalerQuality quality,
- gfx::Size src_size,
- gfx::Rect src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- std::deque<GLHelperScaling::ScaleOp>* x_ops,
- std::deque<GLHelperScaling::ScaleOp>* y_ops,
- std::vector<ScalerStage>* scaler_stages) {
- while (!x_ops->empty() || !y_ops->empty()) {
- gfx::Size intermediate_size = src_subrect.size();
- std::deque<ScaleOp>* current_queue = NULL;
-
- if (!y_ops->empty()) {
- current_queue = y_ops;
- } else {
- current_queue = x_ops;
- }
-
- ShaderType current_shader = SHADER_BILINEAR;
- switch (current_queue->front().scale_factor) {
- case 0:
- if (quality == GLHelper::SCALER_QUALITY_BEST) {
- current_shader = SHADER_BICUBIC_UPSCALE;
- }
- break;
- case 2:
- if (quality == GLHelper::SCALER_QUALITY_BEST) {
- current_shader = SHADER_BICUBIC_HALF_1D;
- }
- break;
- case 3:
- DCHECK(quality != GLHelper::SCALER_QUALITY_BEST);
- current_shader = SHADER_BILINEAR3;
- break;
- default:
- NOTREACHED();
- }
- bool scale_x = current_queue->front().scale_x;
- current_queue->front().UpdateSize(&intermediate_size);
- current_queue->pop_front();
-
- // Optimization: Sometimes we can combine 2-4 scaling operations into
- // one operation.
- if (quality == GLHelper::SCALER_QUALITY_GOOD) {
- if (!current_queue->empty() && current_shader == SHADER_BILINEAR) {
- // Combine two steps in the same dimension.
- current_queue->front().UpdateSize(&intermediate_size);
- current_queue->pop_front();
- current_shader = SHADER_BILINEAR2;
- if (!current_queue->empty()) {
- // Combine three steps in the same dimension.
- current_queue->front().UpdateSize(&intermediate_size);
- current_queue->pop_front();
- current_shader = SHADER_BILINEAR4;
- }
- }
- // Check if we can combine some steps in the other dimension as well.
- // Since all shaders currently use GL_LINEAR, we can easily scale up
- // or scale down by exactly 2x at the same time as we do another
- // operation. Currently, the following mergers are supported:
- // * 1 bilinear Y-pass with 1 bilinear X-pass (up or down)
- // * 2 bilinear Y-passes with 2 bilinear X-passes
- // * 1 bilinear Y-pass with N bilinear X-pass
- // * N bilinear Y-passes with 1 bilinear X-pass (down only)
- // Measurements indicate that generalizing this for 3x3 and 4x4
- // makes it slower on some platforms, such as the Pixel.
- if (!scale_x && x_ops->size() > 0 && x_ops->front().scale_factor <= 2) {
- int x_passes = 0;
- if (current_shader == SHADER_BILINEAR2 && x_ops->size() >= 2) {
- // 2y + 2x passes
- x_passes = 2;
- current_shader = SHADER_BILINEAR2X2;
- } else if (current_shader == SHADER_BILINEAR) {
- // 1y + Nx passes
- scale_x = true;
- switch (x_ops->size()) {
- case 0:
- NOTREACHED();
- case 1:
- if (x_ops->front().scale_factor == 3) {
- current_shader = SHADER_BILINEAR3;
- }
- x_passes = 1;
- break;
- case 2:
- x_passes = 2;
- current_shader = SHADER_BILINEAR2;
- break;
- default:
- x_passes = 3;
- current_shader = SHADER_BILINEAR4;
- break;
- }
- } else if (x_ops->front().scale_factor == 2) {
- // Ny + 1x-downscale
- x_passes = 1;
- }
-
- for (int i = 0; i < x_passes; i++) {
- x_ops->front().UpdateSize(&intermediate_size);
- x_ops->pop_front();
- }
- }
- }
-
- scaler_stages->push_back(ScalerStage(current_shader,
- src_size,
- src_subrect,
- intermediate_size,
- scale_x,
- vertically_flip_texture,
- swizzle));
- src_size = intermediate_size;
- src_subrect = gfx::Rect(intermediate_size);
- vertically_flip_texture = false;
- swizzle = false;
- }
-}
-
-void GLHelperScaling::ComputeScalerStages(
- GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- std::vector<ScalerStage>* scaler_stages) {
- if (quality == GLHelper::SCALER_QUALITY_FAST ||
- src_subrect.size() == dst_size) {
- scaler_stages->push_back(ScalerStage(SHADER_BILINEAR,
- src_size,
- src_subrect,
- dst_size,
- false,
- vertically_flip_texture,
- swizzle));
- return;
- }
-
- std::deque<GLHelperScaling::ScaleOp> x_ops, y_ops;
- GLHelperScaling::ScaleOp::AddOps(src_subrect.width(),
- dst_size.width(),
- true,
- quality == GLHelper::SCALER_QUALITY_GOOD,
- &x_ops);
- GLHelperScaling::ScaleOp::AddOps(src_subrect.height(),
- dst_size.height(),
- false,
- quality == GLHelper::SCALER_QUALITY_GOOD,
- &y_ops);
-
- ConvertScalerOpsToScalerStages(quality,
- src_size,
- src_subrect,
- dst_size,
- vertically_flip_texture,
- swizzle,
- &x_ops,
- &y_ops,
- scaler_stages);
-}
-
-GLHelper::ScalerInterface* GLHelperScaling::CreateScaler(
- GLHelper::ScalerQuality quality,
- gfx::Size src_size,
- gfx::Rect src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle) {
- std::vector<ScalerStage> scaler_stages;
- ComputeScalerStages(quality,
- src_size,
- src_subrect,
- dst_size,
- vertically_flip_texture,
- swizzle,
- &scaler_stages);
-
- ScalerImpl* ret = NULL;
- for (unsigned int i = 0; i < scaler_stages.size(); i++) {
- ret = new ScalerImpl(gl_, this, scaler_stages[i], ret, NULL);
- }
- return ret;
-}
-
-GLHelper::ScalerInterface* GLHelperScaling::CreatePlanarScaler(
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- const float color_weights[4]) {
- ScalerStage stage(SHADER_PLANAR,
- src_size,
- src_subrect,
- dst_size,
- true,
- vertically_flip_texture,
- swizzle);
- return new ScalerImpl(gl_, this, stage, NULL, color_weights);
-}
-
-GLHelperScaling::ShaderInterface* GLHelperScaling::CreateYuvMrtShader(
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- ShaderType shader) {
- DCHECK(shader == SHADER_YUV_MRT_PASS1 || shader == SHADER_YUV_MRT_PASS2);
- ScalerStage stage(shader,
- src_size,
- src_subrect,
- dst_size,
- true,
- vertically_flip_texture,
- swizzle);
- return new ScalerImpl(gl_, this, stage, NULL, NULL);
-}
-
-const GLfloat GLHelperScaling::kVertexAttributes[] = {
- -1.0f, -1.0f, 0.0f, 0.0f, // vertex 0
- 1.0f, -1.0f, 1.0f, 0.0f, // vertex 1
- -1.0f, 1.0f, 0.0f, 1.0f, // vertex 2
- 1.0f, 1.0f, 1.0f, 1.0f, }; // vertex 3
-
-void GLHelperScaling::InitBuffer() {
- ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(gl_,
- vertex_attributes_buffer_);
- gl_->BufferData(GL_ARRAY_BUFFER,
- sizeof(kVertexAttributes),
- kVertexAttributes,
- GL_STATIC_DRAW);
-}
-
-scoped_refptr<ShaderProgram> GLHelperScaling::GetShaderProgram(ShaderType type,
- bool swizzle) {
- ShaderProgramKeyType key(type, swizzle);
- scoped_refptr<ShaderProgram>& cache_entry(shader_programs_[key]);
- if (!cache_entry.get()) {
- cache_entry = new ShaderProgram(gl_, helper_);
- std::basic_string<GLchar> vertex_program;
- std::basic_string<GLchar> fragment_program;
- std::basic_string<GLchar> vertex_header;
- std::basic_string<GLchar> fragment_directives;
- std::basic_string<GLchar> fragment_header;
- std::basic_string<GLchar> shared_variables;
-
- vertex_header.append(
- "precision highp float;\n"
- "attribute vec2 a_position;\n"
- "attribute vec2 a_texcoord;\n"
- "uniform vec4 src_subrect;\n");
-
- fragment_header.append(
- "precision mediump float;\n"
- "uniform sampler2D s_texture;\n");
-
- vertex_program.append(
- " gl_Position = vec4(a_position, 0.0, 1.0);\n"
- " vec2 texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;\n");
-
- switch (type) {
- case SHADER_BILINEAR:
- shared_variables.append("varying vec2 v_texcoord;\n");
- vertex_program.append(" v_texcoord = texcoord;\n");
- fragment_program.append(
- " gl_FragColor = texture2D(s_texture, v_texcoord);\n");
- break;
-
- case SHADER_BILINEAR2:
- // This is equivialent to two passes of the BILINEAR shader above.
- // It can be used to scale an image down 1.0x-2.0x in either dimension,
- // or exactly 4x.
- shared_variables.append(
- "varying vec4 v_texcoords;\n"); // 2 texcoords packed in one quad
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 4.0;\n"
- " v_texcoords.xy = texcoord + step;\n"
- " v_texcoords.zw = texcoord - step;\n");
-
- fragment_program.append(
- " gl_FragColor = (texture2D(s_texture, v_texcoords.xy) +\n"
- " texture2D(s_texture, v_texcoords.zw)) / 2.0;\n");
- break;
-
- case SHADER_BILINEAR3:
- // This is kind of like doing 1.5 passes of the BILINEAR shader.
- // It can be used to scale an image down 1.5x-3.0x, or exactly 6x.
- shared_variables.append(
- "varying vec4 v_texcoords1;\n" // 2 texcoords packed in one quad
- "varying vec2 v_texcoords2;\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 3.0;\n"
- " v_texcoords1.xy = texcoord + step;\n"
- " v_texcoords1.zw = texcoord;\n"
- " v_texcoords2 = texcoord - step;\n");
- fragment_program.append(
- " gl_FragColor = (texture2D(s_texture, v_texcoords1.xy) +\n"
- " texture2D(s_texture, v_texcoords1.zw) +\n"
- " texture2D(s_texture, v_texcoords2)) / 3.0;\n");
- break;
-
- case SHADER_BILINEAR4:
- // This is equivialent to three passes of the BILINEAR shader above,
- // It can be used to scale an image down 2.0x-4.0x or exactly 8x.
- shared_variables.append("varying vec4 v_texcoords[2];\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 8.0;\n"
- " v_texcoords[0].xy = texcoord - step * 3.0;\n"
- " v_texcoords[0].zw = texcoord - step;\n"
- " v_texcoords[1].xy = texcoord + step;\n"
- " v_texcoords[1].zw = texcoord + step * 3.0;\n");
- fragment_program.append(
- " gl_FragColor = (\n"
- " texture2D(s_texture, v_texcoords[0].xy) +\n"
- " texture2D(s_texture, v_texcoords[0].zw) +\n"
- " texture2D(s_texture, v_texcoords[1].xy) +\n"
- " texture2D(s_texture, v_texcoords[1].zw)) / 4.0;\n");
- break;
-
- case SHADER_BILINEAR2X2:
- // This is equivialent to four passes of the BILINEAR shader above.
- // Two in each dimension. It can be used to scale an image down
- // 1.0x-2.0x in both X and Y directions. Or, it could be used to
- // scale an image down by exactly 4x in both dimensions.
- shared_variables.append("varying vec4 v_texcoords[2];\n");
- vertex_header.append("uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = src_subrect.zw / 4.0 / dst_pixelsize;\n"
- " v_texcoords[0].xy = texcoord + vec2(step.x, step.y);\n"
- " v_texcoords[0].zw = texcoord + vec2(step.x, -step.y);\n"
- " v_texcoords[1].xy = texcoord + vec2(-step.x, step.y);\n"
- " v_texcoords[1].zw = texcoord + vec2(-step.x, -step.y);\n");
- fragment_program.append(
- " gl_FragColor = (\n"
- " texture2D(s_texture, v_texcoords[0].xy) +\n"
- " texture2D(s_texture, v_texcoords[0].zw) +\n"
- " texture2D(s_texture, v_texcoords[1].xy) +\n"
- " texture2D(s_texture, v_texcoords[1].zw)) / 4.0;\n");
- break;
-
- case SHADER_BICUBIC_HALF_1D:
- // This scales down texture by exactly half in one dimension.
- // directions in one pass. We use bilinear lookup to reduce
- // the number of texture reads from 8 to 4
- shared_variables.append(
- "const float CenterDist = 99.0 / 140.0;\n"
- "const float LobeDist = 11.0 / 4.0;\n"
- "const float CenterWeight = 35.0 / 64.0;\n"
- "const float LobeWeight = -3.0 / 64.0;\n"
- "varying vec4 v_texcoords[2];\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 src_pixelsize;\n");
- vertex_program.append(
- " vec2 step = src_subrect.zw * scaling_vector / src_pixelsize;\n"
- " v_texcoords[0].xy = texcoord - LobeDist * step;\n"
- " v_texcoords[0].zw = texcoord - CenterDist * step;\n"
- " v_texcoords[1].xy = texcoord + CenterDist * step;\n"
- " v_texcoords[1].zw = texcoord + LobeDist * step;\n");
- fragment_program.append(
- " gl_FragColor = \n"
- // Lobe pixels
- " (texture2D(s_texture, v_texcoords[0].xy) +\n"
- " texture2D(s_texture, v_texcoords[1].zw)) *\n"
- " LobeWeight +\n"
- // Center pixels
- " (texture2D(s_texture, v_texcoords[0].zw) +\n"
- " texture2D(s_texture, v_texcoords[1].xy)) *\n"
- " CenterWeight;\n");
- break;
-
- case SHADER_BICUBIC_UPSCALE:
- // When scaling up, we need 4 texture reads, but we can
- // save some instructions because will know in which range of
- // the bicubic function each call call to the bicubic function
- // will be in.
- // Also, when sampling the bicubic function like this, the sum
- // is always exactly one, so we can skip normalization as well.
- shared_variables.append("varying vec2 v_texcoord;\n");
- vertex_program.append(" v_texcoord = texcoord;\n");
- fragment_header.append(
- "uniform vec2 src_pixelsize;\n"
- "uniform vec2 scaling_vector;\n"
- "const float a = -0.5;\n"
- // This function is equivialent to calling the bicubic
- // function with x-1, x, 1-x and 2-x
- // (assuming 0 <= x < 1)
- "vec4 filt4(float x) {\n"
- " return vec4(x * x * x, x * x, x, 1) *\n"
- " mat4( a, -2.0 * a, a, 0.0,\n"
- " a + 2.0, -a - 3.0, 0.0, 1.0,\n"
- " -a - 2.0, 3.0 + 2.0 * a, -a, 0.0,\n"
- " -a, a, 0.0, 0.0);\n"
- "}\n"
- "mat4 pixels_x(vec2 pos, vec2 step) {\n"
- " return mat4(\n"
- " texture2D(s_texture, pos - step),\n"
- " texture2D(s_texture, pos),\n"
- " texture2D(s_texture, pos + step),\n"
- " texture2D(s_texture, pos + step * 2.0));\n"
- "}\n");
- fragment_program.append(
- " vec2 pixel_pos = v_texcoord * src_pixelsize - \n"
- " scaling_vector / 2.0;\n"
- " float frac = fract(dot(pixel_pos, scaling_vector));\n"
- " vec2 base = (floor(pixel_pos) + vec2(0.5)) / src_pixelsize;\n"
- " vec2 step = scaling_vector / src_pixelsize;\n"
- " gl_FragColor = pixels_x(base, step) * filt4(frac);\n");
- break;
-
- case SHADER_PLANAR:
- // Converts four RGBA pixels into one pixel. Each RGBA
- // pixel will be dot-multiplied with the color weights and
- // then placed into a component of the output. This is used to
- // convert RGBA textures into Y, U and V textures. We do this
- // because single-component textures are not renderable on all
- // architectures.
- shared_variables.append("varying vec4 v_texcoords[2];\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 4.0;\n"
- " v_texcoords[0].xy = texcoord - step * 1.5;\n"
- " v_texcoords[0].zw = texcoord - step * 0.5;\n"
- " v_texcoords[1].xy = texcoord + step * 0.5;\n"
- " v_texcoords[1].zw = texcoord + step * 1.5;\n");
- fragment_header.append("uniform vec4 color_weights;\n");
- fragment_program.append(
- " gl_FragColor = color_weights * mat4(\n"
- " vec4(texture2D(s_texture, v_texcoords[0].xy).rgb, 1.0),\n"
- " vec4(texture2D(s_texture, v_texcoords[0].zw).rgb, 1.0),\n"
- " vec4(texture2D(s_texture, v_texcoords[1].xy).rgb, 1.0),\n"
- " vec4(texture2D(s_texture, v_texcoords[1].zw).rgb, 1.0));\n");
- break;
-
- case SHADER_YUV_MRT_PASS1:
- // RGB24 to YV12 in two passes; writing two 8888 targets each pass.
- //
- // YV12 is full-resolution luma and half-resolution blue/red chroma.
- //
- // (original)
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // RGBX RGBX RGBX RGBX RGBX RGBX RGBX RGBX
- // |
- // | (y plane) (temporary)
- // | YYYY YYYY UUVV UUVV
- // +--> { YYYY YYYY + UUVV UUVV }
- // YYYY YYYY UUVV UUVV
- // First YYYY YYYY UUVV UUVV
- // pass YYYY YYYY UUVV UUVV
- // YYYY YYYY UUVV UUVV
- // |
- // | (u plane) (v plane)
- // Second | UUUU VVVV
- // pass +--> { UUUU + VVVV }
- // UUUU VVVV
- //
- shared_variables.append("varying vec4 v_texcoords[2];\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 4.0;\n"
- " v_texcoords[0].xy = texcoord - step * 1.5;\n"
- " v_texcoords[0].zw = texcoord - step * 0.5;\n"
- " v_texcoords[1].xy = texcoord + step * 0.5;\n"
- " v_texcoords[1].zw = texcoord + step * 1.5;\n");
- fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
- fragment_header.append(
- "const vec3 kRGBtoY = vec3(0.257, 0.504, 0.098);\n"
- "const float kYBias = 0.0625;\n"
- // Divide U and V by two to compensate for averaging below.
- "const vec3 kRGBtoU = vec3(-0.148, -0.291, 0.439) / 2.0;\n"
- "const vec3 kRGBtoV = vec3(0.439, -0.368, -0.071) / 2.0;\n"
- "const float kUVBias = 0.5;\n");
- fragment_program.append(
- " vec3 pixel1 = texture2D(s_texture, v_texcoords[0].xy).rgb;\n"
- " vec3 pixel2 = texture2D(s_texture, v_texcoords[0].zw).rgb;\n"
- " vec3 pixel3 = texture2D(s_texture, v_texcoords[1].xy).rgb;\n"
- " vec3 pixel4 = texture2D(s_texture, v_texcoords[1].zw).rgb;\n"
- " vec3 pixel12 = pixel1 + pixel2;\n"
- " vec3 pixel34 = pixel3 + pixel4;\n"
- " gl_FragData[0] = vec4(dot(pixel1, kRGBtoY),\n"
- " dot(pixel2, kRGBtoY),\n"
- " dot(pixel3, kRGBtoY),\n"
- " dot(pixel4, kRGBtoY)) + kYBias;\n"
- " gl_FragData[1] = vec4(dot(pixel12, kRGBtoU),\n"
- " dot(pixel34, kRGBtoU),\n"
- " dot(pixel12, kRGBtoV),\n"
- " dot(pixel34, kRGBtoV)) + kUVBias;\n");
- break;
-
- case SHADER_YUV_MRT_PASS2:
- // We're just sampling two pixels and unswizzling them. There's
- // no need to do vertical scaling with math, since bilinear
- // interpolation in the sampler takes care of that.
- shared_variables.append("varying vec4 v_texcoords;\n");
- vertex_header.append(
- "uniform vec2 scaling_vector;\n"
- "uniform vec2 dst_pixelsize;\n");
- vertex_program.append(
- " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
- " step /= 2.0;\n"
- " v_texcoords.xy = texcoord - step * 0.5;\n"
- " v_texcoords.zw = texcoord + step * 0.5;\n");
- fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
- fragment_program.append(
- " vec4 lo_uuvv = texture2D(s_texture, v_texcoords.xy);\n"
- " vec4 hi_uuvv = texture2D(s_texture, v_texcoords.zw);\n"
- " gl_FragData[0] = vec4(lo_uuvv.rg, hi_uuvv.rg);\n"
- " gl_FragData[1] = vec4(lo_uuvv.ba, hi_uuvv.ba);\n");
- break;
- }
- if (swizzle) {
- switch(type) {
- case SHADER_YUV_MRT_PASS1:
- fragment_program.append(" gl_FragData[0] = gl_FragData[0].bgra;\n");
- break;
- case SHADER_YUV_MRT_PASS2:
- fragment_program.append(" gl_FragData[0] = gl_FragData[0].bgra;\n");
- fragment_program.append(" gl_FragData[1] = gl_FragData[1].bgra;\n");
- break;
- default:
- fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n");
- break;
- }
- }
-
- vertex_program = vertex_header + shared_variables + "void main() {\n" +
- vertex_program + "}\n";
-
- fragment_program = fragment_directives + fragment_header +
- shared_variables + "void main() {\n" + fragment_program +
- "}\n";
-
- cache_entry->Setup(vertex_program.c_str(), fragment_program.c_str());
- }
- return cache_entry;
-}
-
-void ShaderProgram::Setup(const GLchar* vertex_shader_text,
- const GLchar* fragment_shader_text) {
- // Shaders to map the source texture to |dst_texture_|.
- GLuint vertex_shader =
- helper_->CompileShaderFromSource(vertex_shader_text, GL_VERTEX_SHADER);
- if (vertex_shader == 0)
- return;
-
- gl_->AttachShader(program_, vertex_shader);
- gl_->DeleteShader(vertex_shader);
-
- GLuint fragment_shader = helper_->CompileShaderFromSource(
- fragment_shader_text, GL_FRAGMENT_SHADER);
- if (fragment_shader == 0)
- return;
- gl_->AttachShader(program_, fragment_shader);
- gl_->DeleteShader(fragment_shader);
-
- gl_->LinkProgram(program_);
-
- GLint link_status = 0;
- gl_->GetProgramiv(program_, GL_LINK_STATUS, &link_status);
- if (!link_status)
- return;
-
- position_location_ = gl_->GetAttribLocation(program_, "a_position");
- texcoord_location_ = gl_->GetAttribLocation(program_, "a_texcoord");
- texture_location_ = gl_->GetUniformLocation(program_, "s_texture");
- src_subrect_location_ = gl_->GetUniformLocation(program_, "src_subrect");
- src_pixelsize_location_ = gl_->GetUniformLocation(program_, "src_pixelsize");
- dst_pixelsize_location_ = gl_->GetUniformLocation(program_, "dst_pixelsize");
- scaling_vector_location_ =
- gl_->GetUniformLocation(program_, "scaling_vector");
- color_weights_location_ = gl_->GetUniformLocation(program_, "color_weights");
- // The only reason fetching these attribute locations should fail is
- // if the context was spontaneously lost (i.e., because the GPU
- // process crashed, perhaps deliberately for testing).
- DCHECK(Initialized() || gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR);
-}
-
-void ShaderProgram::UseProgram(const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool scale_x,
- bool flip_y,
- GLfloat color_weights[4]) {
- gl_->UseProgram(program_);
-
- // OpenGL defines the last parameter to VertexAttribPointer as type
- // "const GLvoid*" even though it is actually an offset into the buffer
- // object's data store and not a pointer to the client's address space.
- const void* offsets[2] = {
- 0, reinterpret_cast<const void*>(2 * sizeof(GLfloat))
- };
-
- gl_->VertexAttribPointer(position_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(GLfloat),
- offsets[0]);
- gl_->EnableVertexAttribArray(position_location_);
-
- gl_->VertexAttribPointer(texcoord_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(GLfloat),
- offsets[1]);
- gl_->EnableVertexAttribArray(texcoord_location_);
-
- gl_->Uniform1i(texture_location_, 0);
-
- // Convert |src_subrect| to texture coordinates.
- GLfloat src_subrect_texcoord[] = {
- static_cast<float>(src_subrect.x()) / src_size.width(),
- static_cast<float>(src_subrect.y()) / src_size.height(),
- static_cast<float>(src_subrect.width()) / src_size.width(),
- static_cast<float>(src_subrect.height()) / src_size.height(), };
- if (flip_y) {
- src_subrect_texcoord[1] += src_subrect_texcoord[3];
- src_subrect_texcoord[3] *= -1.0;
- }
- gl_->Uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
-
- gl_->Uniform2f(src_pixelsize_location_, src_size.width(), src_size.height());
- gl_->Uniform2f(dst_pixelsize_location_,
- static_cast<float>(dst_size.width()),
- static_cast<float>(dst_size.height()));
-
- gl_->Uniform2f(
- scaling_vector_location_, scale_x ? 1.0 : 0.0, scale_x ? 0.0 : 1.0);
- gl_->Uniform4fv(color_weights_location_, 1, color_weights);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gl_helper_scaling.h b/chromium/content/common/gpu/client/gl_helper_scaling.h
deleted file mode 100644
index 6157d8e0d9b..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_scaling.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2013 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 CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
-#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
-
-#include <deque>
-#include <map>
-#include <vector>
-
-#include "base/macros.h"
-#include "content/common/gpu/client/gl_helper.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-
-class ShaderProgram;
-class ScalerImpl;
-class GLHelperTest;
-
-// Implements GPU texture scaling methods.
-// Note that you should probably not use this class directly.
-// See gl_helper.cc::CreateScaler instead.
-class CONTENT_EXPORT GLHelperScaling {
- public:
- enum ShaderType {
- SHADER_BILINEAR,
- SHADER_BILINEAR2,
- SHADER_BILINEAR3,
- SHADER_BILINEAR4,
- SHADER_BILINEAR2X2,
- SHADER_BICUBIC_UPSCALE,
- SHADER_BICUBIC_HALF_1D,
- SHADER_PLANAR,
- SHADER_YUV_MRT_PASS1,
- SHADER_YUV_MRT_PASS2,
- };
-
- // Similar to ScalerInterface, but can generate multiple outputs.
- // Used for YUV conversion in gl_helper.c
- class CONTENT_EXPORT ShaderInterface {
- public:
- ShaderInterface() {}
- virtual ~ShaderInterface() {}
- // Note that the src_texture will have the min/mag filter set to GL_LINEAR
- // and wrap_s/t set to CLAMP_TO_EDGE in this call.
- virtual void Execute(GLuint source_texture,
- const std::vector<GLuint>& dest_textures) = 0;
- };
-
- typedef std::pair<ShaderType, bool> ShaderProgramKeyType;
-
- GLHelperScaling(gpu::gles2::GLES2Interface* gl,
- GLHelper* helper);
- ~GLHelperScaling();
- void InitBuffer();
-
- GLHelper::ScalerInterface* CreateScaler(
- GLHelper::ScalerQuality quality,
- gfx::Size src_size,
- gfx::Rect src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle);
-
- GLHelper::ScalerInterface* CreatePlanarScaler(
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- const float color_weights[4]);
-
- ShaderInterface* CreateYuvMrtShader(
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- ShaderType shader);
-
- private:
- // A ScaleOp represents a pass in a scaler pipeline, in one dimension.
- // Note that when quality is GOOD, multiple scaler passes will be
- // combined into one operation for increased performance.
- // Exposed in the header file for testing purposes.
- struct ScaleOp {
- ScaleOp(int factor, bool x, int size)
- : scale_factor(factor), scale_x(x), scale_size(size) {
- }
-
- // Calculate a set of ScaleOp needed to convert an image of size
- // |src| into an image of size |dst|. If |scale_x| is true, then
- // the calculations are for the X axis of the image, otherwise Y.
- // If |allow3| is true, we can use a SHADER_BILINEAR3 to replace
- // a scale up and scale down with a 3-tap bilinear scale.
- // The calculated ScaleOps are added to |ops|.
- static void AddOps(int src,
- int dst,
- bool scale_x,
- bool allow3,
- std::deque<ScaleOp>* ops) {
- int num_downscales = 0;
- if (allow3 && dst * 3 >= src && dst * 2 < src) {
- // Technically, this should be a scale up and then a
- // scale down, but it makes the optimization code more
- // complicated.
- ops->push_back(ScaleOp(3, scale_x, dst));
- return;
- }
- while ((dst << num_downscales) < src) {
- num_downscales++;
- }
- if ((dst << num_downscales) != src) {
- ops->push_back(ScaleOp(0, scale_x, dst << num_downscales));
- }
- while (num_downscales) {
- num_downscales--;
- ops->push_back(ScaleOp(2, scale_x, dst << num_downscales));
- }
- }
-
- // Update |size| to its new size. Before calling this function
- // |size| should be the size of the input image. After calling it,
- // |size| will be the size of the image after this particular
- // scaling operation.
- void UpdateSize(gfx::Size* subrect) {
- if (scale_x) {
- subrect->set_width(scale_size);
- } else {
- subrect->set_height(scale_size);
- }
- }
-
- // A scale factor of 0 means upscale
- // 2 means 50% scale
- // 3 means 33% scale, etc.
- int scale_factor;
- bool scale_x; // Otherwise y
- int scale_size; // Size to scale to.
- };
-
- // Full specification for a single scaling stage.
- struct ScalerStage {
- ScalerStage(ShaderType shader_,
- gfx::Size src_size_,
- gfx::Rect src_subrect_,
- gfx::Size dst_size_,
- bool scale_x_,
- bool vertically_flip_texture_,
- bool swizzle_);
- ShaderType shader;
- gfx::Size src_size;
- gfx::Rect src_subrect;
- gfx::Size dst_size;
- bool scale_x;
- bool vertically_flip_texture;
- bool swizzle;
- };
-
- // Compute a vector of scaler stages for a particular
- // set of input/output parameters.
- void ComputeScalerStages(GLHelper::ScalerQuality quality,
- const gfx::Size& src_size,
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- std::vector<ScalerStage> *scaler_stages);
-
- // Take two queues of ScaleOp structs and generate a
- // vector of scaler stages. This is the second half of
- // ComputeScalerStages.
- void ConvertScalerOpsToScalerStages(
- GLHelper::ScalerQuality quality,
- gfx::Size src_size,
- gfx::Rect src_subrect,
- const gfx::Size& dst_size,
- bool vertically_flip_texture,
- bool swizzle,
- std::deque<GLHelperScaling::ScaleOp>* x_ops,
- std::deque<GLHelperScaling::ScaleOp>* y_ops,
- std::vector<ScalerStage> *scaler_stages);
-
-
- scoped_refptr<ShaderProgram> GetShaderProgram(ShaderType type, bool swizzle);
-
- // Interleaved array of 2-dimentional vertex positions (x, y) and
- // 2-dimentional texture coordinates (s, t).
- static const GLfloat kVertexAttributes[];
-
- gpu::gles2::GLES2Interface* gl_;
- GLHelper* helper_;
-
- // The buffer that holds the vertices and the texture coordinates data for
- // drawing a quad.
- ScopedBuffer vertex_attributes_buffer_;
-
- std::map<ShaderProgramKeyType,
- scoped_refptr<ShaderProgram> > shader_programs_;
-
- friend class ShaderProgram;
- friend class ScalerImpl;
- friend class GLHelperTest;
- DISALLOW_COPY_AND_ASSIGN(GLHelperScaling);
-};
-
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
diff --git a/chromium/content/common/gpu/client/gl_helper_unittest.cc b/chromium/content/common/gpu/client/gl_helper_unittest.cc
deleted file mode 100644
index 57022351c51..00000000000
--- a/chromium/content/common/gpu/client/gl_helper_unittest.cc
+++ /dev/null
@@ -1,2016 +0,0 @@
-// Copyright 2014 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 <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <cmath>
-#include <string>
-#include <vector>
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES2/gl2extchromium.h>
-
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/json/json_reader.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/gl_helper.h"
-#include "content/common/gpu/client/gl_helper_readback_support.h"
-#include "content/common/gpu/client/gl_helper_scaling.h"
-#include "content/public/test/unittest_test_suite.h"
-#include "content/test/content_test_suite.h"
-#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
-#include "media/base/video_frame.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkTypes.h"
-#include "ui/gl/gl_implementation.h"
-
-#if defined(OS_MACOSX)
-#include "base/mac/scoped_nsautorelease_pool.h"
-#endif
-
-namespace content {
-
-using blink::WebGLId;
-using blink::WebGraphicsContext3D;
-using gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl;
-
-content::GLHelper::ScalerQuality kQualities[] = {
- content::GLHelper::SCALER_QUALITY_BEST,
- content::GLHelper::SCALER_QUALITY_GOOD,
- content::GLHelper::SCALER_QUALITY_FAST, };
-
-const char* kQualityNames[] = {"best", "good", "fast", };
-
-class GLHelperTest : public testing::Test {
- protected:
- void SetUp() override {
- WebGraphicsContext3D::Attributes attributes;
- bool lose_context_when_out_of_memory = false;
- context_ =
- WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
- attributes, lose_context_when_out_of_memory);
- context_->InitializeOnCurrentThread();
- context_support_ = context_->GetContextSupport();
- helper_.reset(
- new content::GLHelper(context_->GetGLInterface(), context_support_));
- helper_scaling_.reset(new content::GLHelperScaling(
- context_->GetGLInterface(), helper_.get()));
- }
-
- void TearDown() override {
- helper_scaling_.reset(NULL);
- helper_.reset(NULL);
- context_.reset(NULL);
- }
-
- void StartTracing(const std::string& filter) {
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- base::trace_event::TraceConfig(filter,
- base::trace_event::RECORD_UNTIL_FULL),
- base::trace_event::TraceLog::RECORDING_MODE);
- }
-
- static void TraceDataCB(
- const base::Callback<void()>& callback,
- std::string* output,
- const scoped_refptr<base::RefCountedString>& json_events_str,
- bool has_more_events) {
- if (output->size() > 1 && !json_events_str->data().empty()) {
- output->append(",");
- }
- output->append(json_events_str->data());
- if (!has_more_events) {
- callback.Run();
- }
- }
-
- // End tracing, return tracing data in a simple map
- // of event name->counts.
- void EndTracing(std::map<std::string, int>* event_counts) {
- std::string json_data = "[";
- base::trace_event::TraceLog::GetInstance()->SetDisabled();
- base::RunLoop run_loop;
- base::trace_event::TraceLog::GetInstance()->Flush(
- base::Bind(&GLHelperTest::TraceDataCB,
- run_loop.QuitClosure(),
- base::Unretained(&json_data)));
- run_loop.Run();
- json_data.append("]");
-
- std::string error_msg;
- scoped_ptr<base::Value> trace_data =
- base::JSONReader::ReadAndReturnError(json_data, 0, NULL, &error_msg);
- CHECK(trace_data)
- << "JSON parsing failed (" << error_msg << ") JSON data:" << std::endl
- << json_data;
-
- base::ListValue* list;
- CHECK(trace_data->GetAsList(&list));
- for (size_t i = 0; i < list->GetSize(); i++) {
- base::Value* item = NULL;
- if (list->Get(i, &item)) {
- base::DictionaryValue* dict;
- CHECK(item->GetAsDictionary(&dict));
- std::string name;
- CHECK(dict->GetString("name", &name));
- std::string trace_type;
- CHECK(dict->GetString("ph", &trace_type));
- // Count all except END traces, as they come in BEGIN/END pairs.
- if (trace_type != "E" && trace_type != "e")
- (*event_counts)[name]++;
- VLOG(1) << "trace name: " << name;
- }
- }
- }
-
- // Bicubic filter kernel function.
- static float Bicubic(float x) {
- const float a = -0.5;
- x = std::abs(x);
- float x2 = x * x;
- float x3 = x2 * x;
- if (x <= 1) {
- return (a + 2) * x3 - (a + 3) * x2 + 1;
- } else if (x < 2) {
- return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a;
- } else {
- return 0.0f;
- }
- }
-
- // Look up a single channel value. Works for 4-channel and single channel
- // bitmaps. Clamp x/y.
- int Channel(SkBitmap* pixels, int x, int y, int c) {
- if (pixels->bytesPerPixel() == 4) {
- uint32_t* data =
- pixels->getAddr32(std::max(0, std::min(x, pixels->width() - 1)),
- std::max(0, std::min(y, pixels->height() - 1)));
- return (*data) >> (c * 8) & 0xff;
- } else {
- DCHECK_EQ(pixels->bytesPerPixel(), 1);
- DCHECK_EQ(c, 0);
- return *pixels->getAddr8(std::max(0, std::min(x, pixels->width() - 1)),
- std::max(0, std::min(y, pixels->height() - 1)));
- }
- }
-
- // Set a single channel value. Works for 4-channel and single channel
- // bitmaps. Clamp x/y.
- void SetChannel(SkBitmap* pixels, int x, int y, int c, int v) {
- DCHECK_GE(x, 0);
- DCHECK_GE(y, 0);
- DCHECK_LT(x, pixels->width());
- DCHECK_LT(y, pixels->height());
- if (pixels->bytesPerPixel() == 4) {
- uint32_t* data = pixels->getAddr32(x, y);
- v = std::max(0, std::min(v, 255));
- *data = (*data & ~(0xffu << (c * 8))) | (v << (c * 8));
- } else {
- DCHECK_EQ(pixels->bytesPerPixel(), 1);
- DCHECK_EQ(c, 0);
- uint8_t* data = pixels->getAddr8(x, y);
- v = std::max(0, std::min(v, 255));
- *data = v;
- }
- }
-
- // Print all the R, G, B or A values from an SkBitmap in a
- // human-readable format.
- void PrintChannel(SkBitmap* pixels, int c) {
- for (int y = 0; y < pixels->height(); y++) {
- std::string formatted;
- for (int x = 0; x < pixels->width(); x++) {
- formatted.append(base::StringPrintf("%3d, ", Channel(pixels, x, y, c)));
- }
- LOG(ERROR) << formatted;
- }
- }
-
- // Print out the individual steps of a scaler pipeline.
- std::string PrintStages(
- const std::vector<GLHelperScaling::ScalerStage>& scaler_stages) {
- std::string ret;
- for (size_t i = 0; i < scaler_stages.size(); i++) {
- ret.append(base::StringPrintf("%dx%d -> %dx%d ",
- scaler_stages[i].src_size.width(),
- scaler_stages[i].src_size.height(),
- scaler_stages[i].dst_size.width(),
- scaler_stages[i].dst_size.height()));
- bool xy_matters = false;
- switch (scaler_stages[i].shader) {
- case GLHelperScaling::SHADER_BILINEAR:
- ret.append("bilinear");
- break;
- case GLHelperScaling::SHADER_BILINEAR2:
- ret.append("bilinear2");
- xy_matters = true;
- break;
- case GLHelperScaling::SHADER_BILINEAR3:
- ret.append("bilinear3");
- xy_matters = true;
- break;
- case GLHelperScaling::SHADER_BILINEAR4:
- ret.append("bilinear4");
- xy_matters = true;
- break;
- case GLHelperScaling::SHADER_BILINEAR2X2:
- ret.append("bilinear2x2");
- break;
- case GLHelperScaling::SHADER_BICUBIC_UPSCALE:
- ret.append("bicubic upscale");
- xy_matters = true;
- break;
- case GLHelperScaling::SHADER_BICUBIC_HALF_1D:
- ret.append("bicubic 1/2");
- xy_matters = true;
- break;
- case GLHelperScaling::SHADER_PLANAR:
- ret.append("planar");
- break;
- case GLHelperScaling::SHADER_YUV_MRT_PASS1:
- ret.append("rgb2yuv pass 1");
- break;
- case GLHelperScaling::SHADER_YUV_MRT_PASS2:
- ret.append("rgb2yuv pass 2");
- break;
- }
-
- if (xy_matters) {
- if (scaler_stages[i].scale_x) {
- ret.append(" X");
- } else {
- ret.append(" Y");
- }
- }
- ret.append("\n");
- }
- return ret;
- }
-
- bool CheckScale(double scale, int samples, bool already_scaled) {
- // 1:1 is valid if there is one sample.
- if (samples == 1 && scale == 1.0) {
- return true;
- }
- // Is it an exact down-scale (50%, 25%, etc.?)
- if (scale == 2.0 * samples) {
- return true;
- }
- // Upscales, only valid if we haven't already scaled in this dimension.
- if (!already_scaled) {
- // Is it a valid bilinear upscale?
- if (samples == 1 && scale <= 1.0) {
- return true;
- }
- // Multi-sample upscale-downscale combination?
- if (scale > samples / 2.0 && scale < samples) {
- return true;
- }
- }
- return false;
- }
-
- // Make sure that the stages of the scaler pipeline are sane.
- void ValidateScalerStages(
- content::GLHelper::ScalerQuality quality,
- const std::vector<GLHelperScaling::ScalerStage>& scaler_stages,
- const gfx::Size& dst_size,
- const std::string& message) {
- bool previous_error = HasFailure();
- // First, check that the input size for each stage is equal to
- // the output size of the previous stage.
- for (size_t i = 1; i < scaler_stages.size(); i++) {
- EXPECT_EQ(scaler_stages[i - 1].dst_size.width(),
- scaler_stages[i].src_size.width());
- EXPECT_EQ(scaler_stages[i - 1].dst_size.height(),
- scaler_stages[i].src_size.height());
- EXPECT_EQ(scaler_stages[i].src_subrect.x(), 0);
- EXPECT_EQ(scaler_stages[i].src_subrect.y(), 0);
- EXPECT_EQ(scaler_stages[i].src_subrect.width(),
- scaler_stages[i].src_size.width());
- EXPECT_EQ(scaler_stages[i].src_subrect.height(),
- scaler_stages[i].src_size.height());
- }
-
- // Check the output size matches the destination of the last stage
- EXPECT_EQ(scaler_stages[scaler_stages.size() - 1].dst_size.width(),
- dst_size.width());
- EXPECT_EQ(scaler_stages[scaler_stages.size() - 1].dst_size.height(),
- dst_size.height());
-
- // Used to verify that up-scales are not attempted after some
- // other scale.
- bool scaled_x = false;
- bool scaled_y = false;
-
- for (size_t i = 0; i < scaler_stages.size(); i++) {
- // Note: 2.0 means scaling down by 50%
- double x_scale =
- static_cast<double>(scaler_stages[i].src_subrect.width()) /
- static_cast<double>(scaler_stages[i].dst_size.width());
- double y_scale =
- static_cast<double>(scaler_stages[i].src_subrect.height()) /
- static_cast<double>(scaler_stages[i].dst_size.height());
-
- int x_samples = 0;
- int y_samples = 0;
-
- // Codify valid scale operations.
- switch (scaler_stages[i].shader) {
- case GLHelperScaling::SHADER_PLANAR:
- case GLHelperScaling::SHADER_YUV_MRT_PASS1:
- case GLHelperScaling::SHADER_YUV_MRT_PASS2:
- EXPECT_TRUE(false) << "Invalid shader.";
- break;
-
- case GLHelperScaling::SHADER_BILINEAR:
- if (quality != content::GLHelper::SCALER_QUALITY_FAST) {
- x_samples = 1;
- y_samples = 1;
- }
- break;
- case GLHelperScaling::SHADER_BILINEAR2:
- x_samples = 2;
- y_samples = 1;
- break;
- case GLHelperScaling::SHADER_BILINEAR3:
- x_samples = 3;
- y_samples = 1;
- break;
- case GLHelperScaling::SHADER_BILINEAR4:
- x_samples = 4;
- y_samples = 1;
- break;
- case GLHelperScaling::SHADER_BILINEAR2X2:
- x_samples = 2;
- y_samples = 2;
- break;
- case GLHelperScaling::SHADER_BICUBIC_UPSCALE:
- if (scaler_stages[i].scale_x) {
- EXPECT_LT(x_scale, 1.0);
- EXPECT_EQ(y_scale, 1.0);
- } else {
- EXPECT_EQ(x_scale, 1.0);
- EXPECT_LT(y_scale, 1.0);
- }
- break;
- case GLHelperScaling::SHADER_BICUBIC_HALF_1D:
- if (scaler_stages[i].scale_x) {
- EXPECT_EQ(x_scale, 2.0);
- EXPECT_EQ(y_scale, 1.0);
- } else {
- EXPECT_EQ(x_scale, 1.0);
- EXPECT_EQ(y_scale, 2.0);
- }
- break;
- }
-
- if (!scaler_stages[i].scale_x) {
- std::swap(x_samples, y_samples);
- }
-
- if (x_samples) {
- EXPECT_TRUE(CheckScale(x_scale, x_samples, scaled_x))
- << "x_scale = " << x_scale;
- }
- if (y_samples) {
- EXPECT_TRUE(CheckScale(y_scale, y_samples, scaled_y))
- << "y_scale = " << y_scale;
- }
-
- if (x_scale != 1.0) {
- scaled_x = true;
- }
- if (y_scale != 1.0) {
- scaled_y = true;
- }
- }
-
- if (HasFailure() && !previous_error) {
- LOG(ERROR) << "Invalid scaler stages: " << message;
- LOG(ERROR) << "Scaler stages:";
- LOG(ERROR) << PrintStages(scaler_stages);
- }
- }
-
- // Compares two bitmaps taking color types into account. Checks whether each
- // component of each pixel is no more than |maxdiff| apart. If bitmaps are not
- // similar enough, prints out |truth|, |other|, |source|, |scaler_stages|
- // and |message|.
- void Compare(SkBitmap* truth,
- SkBitmap* other,
- int maxdiff,
- SkBitmap* source,
- const std::vector<GLHelperScaling::ScalerStage>& scaler_stages,
- std::string message) {
- EXPECT_EQ(truth->width(), other->width());
- EXPECT_EQ(truth->height(), other->height());
- bool swizzle = (truth->colorType() == kRGBA_8888_SkColorType &&
- other->colorType() == kBGRA_8888_SkColorType) ||
- (truth->colorType() == kBGRA_8888_SkColorType &&
- other->colorType() == kRGBA_8888_SkColorType);
- EXPECT_TRUE(swizzle || truth->colorType() == other->colorType());
- int bpp = truth->bytesPerPixel();
- for (int x = 0; x < truth->width(); x++) {
- for (int y = 0; y < truth->height(); y++) {
- for (int c = 0; c < bpp; c++) {
- int a = Channel(truth, x, y, c);
- // swizzle when comparing if needed
- int b = swizzle && (c == 0 || c == 2)
- ? Channel(other, x, y, (c + 2) & 2)
- : Channel(other, x, y, c);
- EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " c=" << c
- << " " << message;
- if (std::abs(a - b) > maxdiff) {
- LOG(ERROR) << "-------expected--------";
- for (int i = 0; i < bpp; i++) {
- LOG(ERROR) << "Channel " << i << ":";
- PrintChannel(truth, i);
- }
- LOG(ERROR) << "-------actual--------";
- for (int i = 0; i < bpp; i++) {
- LOG(ERROR) << "Channel " << i << ":";
- PrintChannel(other, i);
- }
- if (source) {
- LOG(ERROR) << "-------original--------";
- for (int i = 0; i < source->bytesPerPixel(); i++) {
- LOG(ERROR) << "Channel " << i << ":";
- PrintChannel(source, i);
- }
- }
- LOG(ERROR) << "-----Scaler stages------";
- LOG(ERROR) << PrintStages(scaler_stages);
- return;
- }
- }
- }
- }
- }
-
- // Get a single R, G, B or A value as a float.
- float ChannelAsFloat(SkBitmap* pixels, int x, int y, int c) {
- return Channel(pixels, x, y, c) / 255.0;
- }
-
- // Works like a GL_LINEAR lookup on an SkBitmap.
- float Bilinear(SkBitmap* pixels, float x, float y, int c) {
- x -= 0.5;
- y -= 0.5;
- int base_x = static_cast<int>(floorf(x));
- int base_y = static_cast<int>(floorf(y));
- x -= base_x;
- y -= base_y;
- return (ChannelAsFloat(pixels, base_x, base_y, c) * (1 - x) * (1 - y) +
- ChannelAsFloat(pixels, base_x + 1, base_y, c) * x * (1 - y) +
- ChannelAsFloat(pixels, base_x, base_y + 1, c) * (1 - x) * y +
- ChannelAsFloat(pixels, base_x + 1, base_y + 1, c) * x * y);
- }
-
- // Encodes an RGBA bitmap to grayscale.
- // Reference implementation for
- // GLHelper::CopyToTextureImpl::EncodeTextureAsGrayscale.
- void EncodeToGrayscaleSlow(SkBitmap* input, SkBitmap* output) {
- const float kRGBtoGrayscaleColorWeights[3] = {0.213f, 0.715f, 0.072f};
- CHECK_EQ(kAlpha_8_SkColorType, output->colorType());
- CHECK_EQ(input->width(), output->width());
- CHECK_EQ(input->height(), output->height());
- CHECK_EQ(input->colorType(), kRGBA_8888_SkColorType);
-
- for (int dst_y = 0; dst_y < output->height(); dst_y++) {
- for (int dst_x = 0; dst_x < output->width(); dst_x++) {
- float c0 = ChannelAsFloat(input, dst_x, dst_y, 0);
- float c1 = ChannelAsFloat(input, dst_x, dst_y, 1);
- float c2 = ChannelAsFloat(input, dst_x, dst_y, 2);
- float value = c0 * kRGBtoGrayscaleColorWeights[0] +
- c1 * kRGBtoGrayscaleColorWeights[1] +
- c2 * kRGBtoGrayscaleColorWeights[2];
- SetChannel(
- output, dst_x, dst_y, 0, static_cast<int>(value * 255.0f + 0.5f));
- }
- }
- }
-
- // Very slow bicubic / bilinear scaler for reference.
- void ScaleSlow(SkBitmap* input,
- SkBitmap* output,
- content::GLHelper::ScalerQuality quality) {
- float xscale = static_cast<float>(input->width()) / output->width();
- float yscale = static_cast<float>(input->height()) / output->height();
- float clamped_xscale = xscale < 1.0 ? 1.0 : 1.0 / xscale;
- float clamped_yscale = yscale < 1.0 ? 1.0 : 1.0 / yscale;
- for (int dst_y = 0; dst_y < output->height(); dst_y++) {
- for (int dst_x = 0; dst_x < output->width(); dst_x++) {
- for (int channel = 0; channel < 4; channel++) {
- float dst_x_in_src = (dst_x + 0.5f) * xscale;
- float dst_y_in_src = (dst_y + 0.5f) * yscale;
-
- float value = 0.0f;
- float sum = 0.0f;
- switch (quality) {
- case content::GLHelper::SCALER_QUALITY_BEST:
- for (int src_y = -10; src_y < input->height() + 10; ++src_y) {
- float coeff_y =
- Bicubic((src_y + 0.5f - dst_y_in_src) * clamped_yscale);
- if (coeff_y == 0.0f) {
- continue;
- }
- for (int src_x = -10; src_x < input->width() + 10; ++src_x) {
- float coeff =
- coeff_y *
- Bicubic((src_x + 0.5f - dst_x_in_src) * clamped_xscale);
- if (coeff == 0.0f) {
- continue;
- }
- sum += coeff;
- float c = ChannelAsFloat(input, src_x, src_y, channel);
- value += c * coeff;
- }
- }
- break;
-
- case content::GLHelper::SCALER_QUALITY_GOOD: {
- int xshift = 0, yshift = 0;
- while ((output->width() << xshift) < input->width()) {
- xshift++;
- }
- while ((output->height() << yshift) < input->height()) {
- yshift++;
- }
- int xmag = 1 << xshift;
- int ymag = 1 << yshift;
- if (xmag == 4 && output->width() * 3 >= input->width()) {
- xmag = 3;
- }
- if (ymag == 4 && output->height() * 3 >= input->height()) {
- ymag = 3;
- }
- for (int x = 0; x < xmag; x++) {
- for (int y = 0; y < ymag; y++) {
- value += Bilinear(input,
- (dst_x * xmag + x + 0.5) * xscale / xmag,
- (dst_y * ymag + y + 0.5) * yscale / ymag,
- channel);
- sum += 1.0;
- }
- }
- break;
- }
-
- case content::GLHelper::SCALER_QUALITY_FAST:
- value = Bilinear(input, dst_x_in_src, dst_y_in_src, channel);
- sum = 1.0;
- }
- value /= sum;
- SetChannel(output,
- dst_x,
- dst_y,
- channel,
- static_cast<int>(value * 255.0f + 0.5f));
- }
- }
- }
- }
-
- void FlipSKBitmap(SkBitmap* bitmap) {
- int bpp = bitmap->bytesPerPixel();
- DCHECK(bpp == 4 || bpp == 1);
- int top_line = 0;
- int bottom_line = bitmap->height() - 1;
- while (top_line < bottom_line) {
- for (int x = 0; x < bitmap->width(); x++) {
- bpp == 4 ? std::swap(*bitmap->getAddr32(x, top_line),
- *bitmap->getAddr32(x, bottom_line))
- : std::swap(*bitmap->getAddr8(x, top_line),
- *bitmap->getAddr8(x, bottom_line));
- }
- top_line++;
- bottom_line--;
- }
- }
-
- // Swaps red and blue channels in each pixel in a 32-bit bitmap.
- void SwizzleSKBitmap(SkBitmap* bitmap) {
- int bpp = bitmap->bytesPerPixel();
- DCHECK(bpp == 4);
- for (int y = 0; y < bitmap->height(); y++) {
- for (int x = 0; x < bitmap->width(); x++) {
- // Swap channels 0 and 2 (red and blue)
- int c0 = Channel(bitmap, x, y, 0);
- int c2 = Channel(bitmap, x, y, 2);
- SetChannel(bitmap, x, y, 2, c0);
- SetChannel(bitmap, x, y, 0, c2);
- }
- }
- }
-
- // gl_helper scales recursively, so we'll need to do that
- // in the reference implementation too.
- void ScaleSlowRecursive(SkBitmap* input,
- SkBitmap* output,
- content::GLHelper::ScalerQuality quality) {
- if (quality == content::GLHelper::SCALER_QUALITY_FAST ||
- quality == content::GLHelper::SCALER_QUALITY_GOOD) {
- ScaleSlow(input, output, quality);
- return;
- }
-
- float xscale = static_cast<float>(output->width()) / input->width();
-
- // This corresponds to all the operations we can do directly.
- float yscale = static_cast<float>(output->height()) / input->height();
- if ((xscale == 1.0f && yscale == 1.0f) ||
- (xscale == 0.5f && yscale == 1.0f) ||
- (xscale == 1.0f && yscale == 0.5f) ||
- (xscale >= 1.0f && yscale == 1.0f) ||
- (xscale == 1.0f && yscale >= 1.0f)) {
- ScaleSlow(input, output, quality);
- return;
- }
-
- // Now we break the problem down into smaller pieces, using the
- // operations available.
- int xtmp = input->width();
- int ytmp = input->height();
-
- if (output->height() != input->height()) {
- ytmp = output->height();
- while (ytmp < input->height() && ytmp * 2 != input->height()) {
- ytmp += ytmp;
- }
- } else {
- xtmp = output->width();
- while (xtmp < input->width() && xtmp * 2 != input->width()) {
- xtmp += xtmp;
- }
- }
-
- SkBitmap tmp;
- tmp.allocN32Pixels(xtmp, ytmp);
-
- ScaleSlowRecursive(input, &tmp, quality);
- ScaleSlowRecursive(&tmp, output, quality);
- }
-
- // Creates an RGBA SkBitmap
- scoped_ptr<SkBitmap> CreateTestBitmap(int width,
- int height,
- int test_pattern) {
- scoped_ptr<SkBitmap> bitmap(new SkBitmap);
- bitmap->allocPixels(SkImageInfo::Make(
- width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
-
- for (int x = 0; x < width; ++x) {
- for (int y = 0; y < height; ++y) {
- switch (test_pattern) {
- case 0: // Smooth test pattern
- SetChannel(bitmap.get(), x, y, 0, x * 10);
- SetChannel(bitmap.get(), x, y, 0, y == 0 ? x * 50 : x * 10);
- SetChannel(bitmap.get(), x, y, 1, y * 10);
- SetChannel(bitmap.get(), x, y, 2, (x + y) * 10);
- SetChannel(bitmap.get(), x, y, 3, 255);
- break;
- case 1: // Small blocks
- SetChannel(bitmap.get(), x, y, 0, x & 1 ? 255 : 0);
- SetChannel(bitmap.get(), x, y, 1, y & 1 ? 255 : 0);
- SetChannel(bitmap.get(), x, y, 2, (x + y) & 1 ? 255 : 0);
- SetChannel(bitmap.get(), x, y, 3, 255);
- break;
- case 2: // Medium blocks
- SetChannel(bitmap.get(), x, y, 0, 10 + x / 2 * 50);
- SetChannel(bitmap.get(), x, y, 1, 10 + y / 3 * 50);
- SetChannel(bitmap.get(), x, y, 2, (x + y) / 5 * 50 + 5);
- SetChannel(bitmap.get(), x, y, 3, 255);
- break;
- }
- }
- }
- return bitmap;
- }
-
- // Binds texture and framebuffer and loads the bitmap pixels into the texture.
- void BindTextureAndFrameBuffer(WebGLId texture,
- WebGLId framebuffer,
- SkBitmap* bitmap,
- int width,
- int height) {
- context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
- context_->bindTexture(GL_TEXTURE_2D, texture);
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- width,
- height,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- bitmap->getPixels());
- }
-
- // Create a test image, transform it using
- // GLHelper::CropScaleReadbackAndCleanTexture and a reference implementation
- // and compare the results.
- void TestCropScaleReadbackAndCleanTexture(int xsize,
- int ysize,
- int scaled_xsize,
- int scaled_ysize,
- int test_pattern,
- SkColorType out_color_type,
- bool swizzle,
- size_t quality_index) {
- DCHECK(out_color_type == kAlpha_8_SkColorType ||
- out_color_type == kRGBA_8888_SkColorType ||
- out_color_type == kBGRA_8888_SkColorType);
- WebGLId src_texture = context_->createTexture();
- WebGLId framebuffer = context_->createFramebuffer();
- scoped_ptr<SkBitmap> input_pixels =
- CreateTestBitmap(xsize, ysize, test_pattern);
- BindTextureAndFrameBuffer(
- src_texture, framebuffer, input_pixels.get(), xsize, ysize);
-
- std::string message = base::StringPrintf(
- "input size: %dx%d "
- "output size: %dx%d "
- "pattern: %d , quality: %s, "
- "out_color_type: %d",
- xsize,
- ysize,
- scaled_xsize,
- scaled_ysize,
- test_pattern,
- kQualityNames[quality_index],
- out_color_type);
-
- // Transform the bitmap using GLHelper::CropScaleReadbackAndCleanTexture.
- SkBitmap output_pixels;
- output_pixels.allocPixels(SkImageInfo::Make(
- scaled_xsize, scaled_ysize, out_color_type, kPremul_SkAlphaType));
- base::RunLoop run_loop;
- gfx::Size encoded_texture_size;
- helper_->CropScaleReadbackAndCleanTexture(
- src_texture,
- gfx::Size(xsize, ysize),
- gfx::Rect(xsize, ysize),
- gfx::Size(scaled_xsize, scaled_ysize),
- static_cast<unsigned char*>(output_pixels.getPixels()),
- out_color_type,
- base::Bind(&callcallback, run_loop.QuitClosure()),
- kQualities[quality_index]);
- run_loop.Run();
- // CropScaleReadbackAndCleanTexture flips the pixels. Flip them back.
- FlipSKBitmap(&output_pixels);
-
- // If the bitmap shouldn't have changed - compare against input.
- if (xsize == scaled_xsize && ysize == scaled_ysize &&
- out_color_type != kAlpha_8_SkColorType) {
- const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
- Compare(input_pixels.get(),
- &output_pixels,
- 0,
- NULL,
- dummy_stages,
- message + " comparing against input");
- return;
- }
-
- // Now transform the bitmap using the reference implementation.
- SkBitmap scaled_pixels;
- scaled_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
- scaled_ysize,
- kRGBA_8888_SkColorType,
- kPremul_SkAlphaType));
- SkBitmap truth_pixels;
- // Step 1: Scale
- ScaleSlowRecursive(
- input_pixels.get(), &scaled_pixels, kQualities[quality_index]);
- // Step 2: Encode to grayscale if needed.
- if (out_color_type == kAlpha_8_SkColorType) {
- truth_pixels.allocPixels(SkImageInfo::Make(
- scaled_xsize, scaled_ysize, out_color_type, kPremul_SkAlphaType));
- EncodeToGrayscaleSlow(&scaled_pixels, &truth_pixels);
- } else {
- truth_pixels = scaled_pixels;
- }
-
- // Now compare the results.
- SkAutoLockPixels lock_input(truth_pixels);
- const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
- Compare(&truth_pixels,
- &output_pixels,
- 2,
- input_pixels.get(),
- dummy_stages,
- message + " comparing against transformed/scaled");
-
- context_->deleteTexture(src_texture);
- context_->deleteFramebuffer(framebuffer);
- }
-
- // Scaling test: Create a test image, scale it using GLHelperScaling
- // and a reference implementation and compare the results.
- void TestScale(int xsize,
- int ysize,
- int scaled_xsize,
- int scaled_ysize,
- int test_pattern,
- size_t quality_index,
- bool flip) {
- WebGLId src_texture = context_->createTexture();
- WebGLId framebuffer = context_->createFramebuffer();
- scoped_ptr<SkBitmap> input_pixels =
- CreateTestBitmap(xsize, ysize, test_pattern);
- BindTextureAndFrameBuffer(
- src_texture, framebuffer, input_pixels.get(), xsize, ysize);
-
- std::string message = base::StringPrintf(
- "input size: %dx%d "
- "output size: %dx%d "
- "pattern: %d quality: %s",
- xsize,
- ysize,
- scaled_xsize,
- scaled_ysize,
- test_pattern,
- kQualityNames[quality_index]);
-
- std::vector<GLHelperScaling::ScalerStage> stages;
- helper_scaling_->ComputeScalerStages(kQualities[quality_index],
- gfx::Size(xsize, ysize),
- gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(scaled_xsize, scaled_ysize),
- flip,
- false,
- &stages);
- ValidateScalerStages(kQualities[quality_index],
- stages,
- gfx::Size(scaled_xsize, scaled_ysize),
- message);
-
- WebGLId dst_texture =
- helper_->CopyAndScaleTexture(src_texture,
- gfx::Size(xsize, ysize),
- gfx::Size(scaled_xsize, scaled_ysize),
- flip,
- kQualities[quality_index]);
-
- SkBitmap output_pixels;
- output_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
- scaled_ysize,
- kRGBA_8888_SkColorType,
- kPremul_SkAlphaType));
-
- helper_->ReadbackTextureSync(
- dst_texture,
- gfx::Rect(0, 0, scaled_xsize, scaled_ysize),
- static_cast<unsigned char*>(output_pixels.getPixels()),
- kRGBA_8888_SkColorType);
- if (flip) {
- // Flip the pixels back.
- FlipSKBitmap(&output_pixels);
- }
-
- // If the bitmap shouldn't have changed - compare against input.
- if (xsize == scaled_xsize && ysize == scaled_ysize) {
- Compare(input_pixels.get(),
- &output_pixels,
- 0,
- NULL,
- stages,
- message + " comparing against input");
- return;
- }
-
- // Now scale the bitmap using the reference implementation.
- SkBitmap truth_pixels;
- truth_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
- scaled_ysize,
- kRGBA_8888_SkColorType,
- kPremul_SkAlphaType));
- ScaleSlowRecursive(
- input_pixels.get(), &truth_pixels, kQualities[quality_index]);
- Compare(&truth_pixels,
- &output_pixels,
- 2,
- input_pixels.get(),
- stages,
- message + " comparing against scaled");
-
- context_->deleteTexture(src_texture);
- context_->deleteTexture(dst_texture);
- context_->deleteFramebuffer(framebuffer);
- }
-
- // Create a scaling pipeline and check that it is made up of
- // valid scaling operations.
- void TestScalerPipeline(size_t quality,
- int xsize,
- int ysize,
- int dst_xsize,
- int dst_ysize) {
- std::vector<GLHelperScaling::ScalerStage> stages;
- helper_scaling_->ComputeScalerStages(kQualities[quality],
- gfx::Size(xsize, ysize),
- gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(dst_xsize, dst_ysize),
- false,
- false,
- &stages);
- ValidateScalerStages(kQualities[quality],
- stages,
- gfx::Size(dst_xsize, dst_ysize),
- base::StringPrintf(
- "input size: %dx%d "
- "output size: %dx%d "
- "quality: %s",
- xsize,
- ysize,
- dst_xsize,
- dst_ysize,
- kQualityNames[quality]));
- }
-
- // Create a scaling pipeline and make sure that the steps
- // are exactly the steps we expect.
- void CheckPipeline(content::GLHelper::ScalerQuality quality,
- int xsize,
- int ysize,
- int dst_xsize,
- int dst_ysize,
- const std::string& description) {
- std::vector<GLHelperScaling::ScalerStage> stages;
- helper_scaling_->ComputeScalerStages(quality,
- gfx::Size(xsize, ysize),
- gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(dst_xsize, dst_ysize),
- false,
- false,
- &stages);
- ValidateScalerStages(content::GLHelper::SCALER_QUALITY_GOOD,
- stages,
- gfx::Size(dst_xsize, dst_ysize),
- "");
- EXPECT_EQ(PrintStages(stages), description);
- }
-
- // Note: Left/Right means Top/Bottom when used for Y dimension.
- enum Margin {
- MarginLeft,
- MarginMiddle,
- MarginRight,
- MarginInvalid,
- };
-
- static Margin NextMargin(Margin m) {
- switch (m) {
- case MarginLeft:
- return MarginMiddle;
- case MarginMiddle:
- return MarginRight;
- case MarginRight:
- return MarginInvalid;
- default:
- return MarginInvalid;
- }
- }
-
- int compute_margin(int insize, int outsize, Margin m) {
- int available = outsize - insize;
- switch (m) {
- default:
- EXPECT_TRUE(false) << "This should not happen.";
- return 0;
- case MarginLeft:
- return 0;
- case MarginMiddle:
- return (available / 2) & ~1;
- case MarginRight:
- return available;
- }
- }
-
- // Convert 0.0 - 1.0 to 0 - 255
- int float_to_byte(float v) {
- int ret = static_cast<int>(floorf(v * 255.0f + 0.5f));
- if (ret < 0) {
- return 0;
- }
- if (ret > 255) {
- return 255;
- }
- return ret;
- }
-
- static void callcallback(const base::Callback<void()>& callback,
- bool result) {
- callback.Run();
- }
-
- void PrintPlane(unsigned char* plane, int xsize, int stride, int ysize) {
- for (int y = 0; y < ysize; y++) {
- std::string formatted;
- for (int x = 0; x < xsize; x++) {
- formatted.append(base::StringPrintf("%3d, ", plane[y * stride + x]));
- }
- LOG(ERROR) << formatted << " (" << (plane + y * stride) << ")";
- }
- }
-
- // Compare two planes make sure that each component of each pixel
- // is no more than |maxdiff| apart.
- void ComparePlane(unsigned char* truth,
- int truth_stride,
- unsigned char* other,
- int other_stride,
- int maxdiff,
- int xsize,
- int ysize,
- SkBitmap* source,
- std::string message) {
- for (int x = 0; x < xsize; x++) {
- for (int y = 0; y < ysize; y++) {
- int a = other[y * other_stride + x];
- int b = truth[y * truth_stride + x];
- EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " "
- << message;
- if (std::abs(a - b) > maxdiff) {
- LOG(ERROR) << "-------expected--------";
- PrintPlane(truth, xsize, truth_stride, ysize);
- LOG(ERROR) << "-------actual--------";
- PrintPlane(other, xsize, other_stride, ysize);
- if (source) {
- LOG(ERROR) << "-------before yuv conversion: red--------";
- PrintChannel(source, 0);
- LOG(ERROR) << "-------before yuv conversion: green------";
- PrintChannel(source, 1);
- LOG(ERROR) << "-------before yuv conversion: blue-------";
- PrintChannel(source, 2);
- }
- return;
- }
- }
- }
- }
-
- void DrawGridToBitmap(int w, int h,
- SkColor background_color,
- SkColor grid_color,
- int grid_pitch,
- int grid_width,
- SkBitmap& bmp) {
- ASSERT_GT(grid_pitch, 0);
- ASSERT_GT(grid_width, 0);
- ASSERT_NE(background_color, grid_color);
-
- for (int y = 0; y < h; ++y) {
- bool y_on_grid = ((y % grid_pitch) < grid_width);
-
- for (int x = 0; x < w; ++x) {
- bool on_grid = (y_on_grid || ((x % grid_pitch) < grid_width));
-
- if (bmp.colorType() == kRGBA_8888_SkColorType ||
- bmp.colorType() == kBGRA_8888_SkColorType) {
- *bmp.getAddr32(x, y) = (on_grid ? grid_color : background_color);
- } else if (bmp.colorType() == kRGB_565_SkColorType) {
- *bmp.getAddr16(x, y) = (on_grid ? grid_color : background_color);
- }
- }
- }
- }
-
- void DrawCheckerToBitmap(int w, int h,
- SkColor color1, SkColor color2,
- int rect_w, int rect_h,
- SkBitmap& bmp) {
- ASSERT_GT(rect_w, 0);
- ASSERT_GT(rect_h, 0);
- ASSERT_NE(color1, color2);
-
- for (int y = 0; y < h; ++y) {
- bool y_bit = (((y / rect_h) & 0x1) == 0);
-
- for (int x = 0; x < w; ++x) {
- bool x_bit = (((x / rect_w) & 0x1) == 0);
-
- bool use_color2 = (x_bit != y_bit); // xor
- if (bmp.colorType() == kRGBA_8888_SkColorType ||
- bmp.colorType() == kBGRA_8888_SkColorType) {
- *bmp.getAddr32(x, y) = (use_color2 ? color2 : color1);
- } else if (bmp.colorType() == kRGB_565_SkColorType) {
- *bmp.getAddr16(x, y) = (use_color2 ? color2 : color1);
- }
- }
- }
- }
-
- bool ColorComponentsClose(SkColor component1,
- SkColor component2,
- SkColorType color_type) {
- int c1 = static_cast<int>(component1);
- int c2 = static_cast<int>(component2);
- bool result = false;
- switch (color_type) {
- case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType:
- result = (std::abs(c1 - c2) == 0);
- break;
- case kRGB_565_SkColorType:
- result = (std::abs(c1 - c2) <= 7);
- break;
- default:
- break;
- }
- return result;
- }
-
- bool ColorsClose(SkColor color1, SkColor color2, SkColorType color_type) {
- bool red = ColorComponentsClose(SkColorGetR(color1),
- SkColorGetR(color2), color_type);
- bool green = ColorComponentsClose(SkColorGetG(color1),
- SkColorGetG(color2), color_type);
- bool blue = ColorComponentsClose(SkColorGetB(color1),
- SkColorGetB(color2), color_type);
- bool alpha = ColorComponentsClose(SkColorGetA(color1),
- SkColorGetA(color2), color_type);
- if (color_type == kRGB_565_SkColorType) {
- return red && blue && green;
- }
- return red && blue && green && alpha;
- }
-
- bool IsEqual(const SkBitmap& bmp1, const SkBitmap& bmp2) {
- if (bmp1.isNull() && bmp2.isNull())
- return true;
- if (bmp1.width() != bmp2.width() ||
- bmp1.height() != bmp2.height()) {
- LOG(ERROR) << "Bitmap geometry check failure";
- return false;
- }
- if (bmp1.colorType() != bmp2.colorType())
- return false;
-
- SkAutoLockPixels lock1(bmp1);
- SkAutoLockPixels lock2(bmp2);
- if (!bmp1.getPixels() || !bmp2.getPixels()) {
- LOG(ERROR) << "Empty Bitmap!";
- return false;
- }
- for (int y = 0; y < bmp1.height(); ++y) {
- for (int x = 0; x < bmp1.width(); ++x) {
- if (!ColorsClose(bmp1.getColor(x,y),
- bmp2.getColor(x,y),
- bmp1.colorType())) {
- LOG(ERROR) << "Bitmap color comparision failure";
- return false;
- }
- }
- }
- return true;
- }
-
- void BindAndAttachTextureWithPixels(GLuint src_texture,
- SkColorType color_type,
- const gfx::Size& src_size,
- const SkBitmap& input_pixels) {
- context_->bindTexture(GL_TEXTURE_2D, src_texture);
- GLenum format = 0;
- switch (color_type) {
- case kBGRA_8888_SkColorType:
- format = GL_BGRA_EXT;
- break;
- case kRGBA_8888_SkColorType:
- format = GL_RGBA;
- break;
- case kRGB_565_SkColorType:
- format = GL_RGB;
- break;
- default:
- NOTREACHED();
- }
- GLenum type = (color_type == kRGB_565_SkColorType) ?
- GL_UNSIGNED_SHORT_5_6_5 : GL_UNSIGNED_BYTE;
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- format,
- src_size.width(),
- src_size.height(),
- 0,
- format,
- type,
- input_pixels.getPixels());
- }
-
- void ReadBackTexture(GLuint src_texture,
- const gfx::Size& src_size,
- unsigned char* pixels,
- SkColorType color_type,
- bool async) {
- if (async) {
- base::RunLoop run_loop;
- helper_->ReadbackTextureAsync(src_texture,
- src_size,
- pixels,
- color_type,
- base::Bind(&callcallback,
- run_loop.QuitClosure()));
- run_loop.Run();
- } else {
- helper_->ReadbackTextureSync(src_texture,
- gfx::Rect(src_size),
- pixels,
- color_type);
- }
- }
- // Test basic format readback.
- bool TestTextureFormatReadback(const gfx::Size& src_size,
- SkColorType color_type,
- bool async) {
- SkImageInfo info =
- SkImageInfo::Make(src_size.width(),
- src_size.height(),
- color_type,
- kPremul_SkAlphaType);
- if (!helper_->IsReadbackConfigSupported(color_type)) {
- LOG(INFO) << "Skipping test format not supported" << color_type;
- return true;
- }
- WebGLId src_texture = context_->createTexture();
- SkBitmap input_pixels;
- input_pixels.allocPixels(info);
- // Test Pattern-1, Fill with Plain color pattern.
- // Erase the input bitmap with red color.
- input_pixels.eraseColor(SK_ColorRED);
- BindAndAttachTextureWithPixels(src_texture,
- color_type,
- src_size,
- input_pixels);
- SkBitmap output_pixels;
- output_pixels.allocPixels(info);
- // Initialize the output bitmap with Green color.
- // When the readback is over output bitmap should have the red color.
- output_pixels.eraseColor(SK_ColorGREEN);
- uint8_t* pixels = static_cast<uint8_t*>(output_pixels.getPixels());
- ReadBackTexture(src_texture, src_size, pixels, color_type, async);
- bool result = IsEqual(input_pixels, output_pixels);
- if (!result) {
- LOG(ERROR) << "Bitmap comparision failure Pattern-1";
- return false;
- }
- const int rect_w = 10, rect_h = 4, src_grid_pitch = 10, src_grid_width = 4;
- const SkColor color1 = SK_ColorRED, color2 = SK_ColorBLUE;
- // Test Pattern-2, Fill with Grid Pattern.
- DrawGridToBitmap(src_size.width(), src_size.height(),
- color2, color1,
- src_grid_pitch, src_grid_width,
- input_pixels);
- BindAndAttachTextureWithPixels(src_texture,
- color_type,
- src_size,
- input_pixels);
- ReadBackTexture(src_texture, src_size, pixels, color_type, async);
- result = IsEqual(input_pixels, output_pixels);
- if (!result) {
- LOG(ERROR) << "Bitmap comparision failure Pattern-2";
- return false;
- }
- // Test Pattern-3, Fill with CheckerBoard Pattern.
- DrawCheckerToBitmap(src_size.width(),
- src_size.height(),
- color1,
- color2, rect_w, rect_h, input_pixels);
- BindAndAttachTextureWithPixels(src_texture,
- color_type,
- src_size,
- input_pixels);
- ReadBackTexture(src_texture, src_size, pixels, color_type, async);
- result = IsEqual(input_pixels, output_pixels);
- if (!result) {
- LOG(ERROR) << "Bitmap comparision failure Pattern-3";
- return false;
- }
- context_->deleteTexture(src_texture);
- if (HasFailure()) {
- return false;
- }
- return true;
- }
-
- // YUV readback test. Create a test pattern, convert to YUV
- // with reference implementation and compare to what gl_helper
- // returns.
- void TestYUVReadback(int xsize,
- int ysize,
- int output_xsize,
- int output_ysize,
- int xmargin,
- int ymargin,
- int test_pattern,
- bool flip,
- bool use_mrt,
- content::GLHelper::ScalerQuality quality) {
- WebGLId src_texture = context_->createTexture();
- SkBitmap input_pixels;
- input_pixels.allocN32Pixels(xsize, ysize);
-
- for (int x = 0; x < xsize; ++x) {
- for (int y = 0; y < ysize; ++y) {
- switch (test_pattern) {
- case 0: // Smooth test pattern
- SetChannel(&input_pixels, x, y, 0, x * 10);
- SetChannel(&input_pixels, x, y, 1, y * 10);
- SetChannel(&input_pixels, x, y, 2, (x + y) * 10);
- SetChannel(&input_pixels, x, y, 3, 255);
- break;
- case 1: // Small blocks
- SetChannel(&input_pixels, x, y, 0, x & 1 ? 255 : 0);
- SetChannel(&input_pixels, x, y, 1, y & 1 ? 255 : 0);
- SetChannel(&input_pixels, x, y, 2, (x + y) & 1 ? 255 : 0);
- SetChannel(&input_pixels, x, y, 3, 255);
- break;
- case 2: // Medium blocks
- SetChannel(&input_pixels, x, y, 0, 10 + x / 2 * 50);
- SetChannel(&input_pixels, x, y, 1, 10 + y / 3 * 50);
- SetChannel(&input_pixels, x, y, 2, (x + y) / 5 * 50 + 5);
- SetChannel(&input_pixels, x, y, 3, 255);
- break;
- }
- }
- }
-
- context_->bindTexture(GL_TEXTURE_2D, src_texture);
- context_->texImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- xsize,
- ysize,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- input_pixels.getPixels());
-
- gpu::Mailbox mailbox;
- context_->genMailboxCHROMIUM(mailbox.name);
- EXPECT_FALSE(mailbox.IsZero());
- context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
- const blink::WGC3Duint64 fence_sync = context_->insertFenceSyncCHROMIUM();
- context_->shallowFlushCHROMIUM();
-
- gpu::SyncToken sync_token;
- ASSERT_TRUE(context_->genSyncTokenCHROMIUM(fence_sync,
- sync_token.GetData()));
-
- std::string message = base::StringPrintf(
- "input size: %dx%d "
- "output size: %dx%d "
- "margin: %dx%d "
- "pattern: %d %s %s",
- xsize,
- ysize,
- output_xsize,
- output_ysize,
- xmargin,
- ymargin,
- test_pattern,
- flip ? "flip" : "noflip",
- flip ? "mrt" : "nomrt");
- scoped_ptr<ReadbackYUVInterface> yuv_reader(
- helper_->CreateReadbackPipelineYUV(
- quality,
- gfx::Size(xsize, ysize),
- gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(xsize, ysize),
- flip,
- use_mrt));
-
- scoped_refptr<media::VideoFrame> output_frame =
- media::VideoFrame::CreateFrame(
- media::PIXEL_FORMAT_YV12,
- // The coded size of the output frame is rounded up to the next
- // 16-byte boundary. This tests that the readback is being
- // positioned inside the frame's visible region, and not dependent
- // on its coded size.
- gfx::Size((output_xsize + 15) & ~15, (output_ysize + 15) & ~15),
- gfx::Rect(0, 0, output_xsize, output_ysize),
- gfx::Size(output_xsize, output_ysize),
- base::TimeDelta::FromSeconds(0));
- scoped_refptr<media::VideoFrame> truth_frame =
- media::VideoFrame::CreateFrame(
- media::PIXEL_FORMAT_YV12, gfx::Size(output_xsize, output_ysize),
- gfx::Rect(0, 0, output_xsize, output_ysize),
- gfx::Size(output_xsize, output_ysize),
- base::TimeDelta::FromSeconds(0));
-
- base::RunLoop run_loop;
- yuv_reader->ReadbackYUV(mailbox, sync_token, output_frame.get(),
- gfx::Point(xmargin, ymargin),
- base::Bind(&callcallback, run_loop.QuitClosure()));
- run_loop.Run();
-
- if (flip) {
- FlipSKBitmap(&input_pixels);
- }
-
- unsigned char* Y = truth_frame->visible_data(media::VideoFrame::kYPlane);
- unsigned char* U = truth_frame->visible_data(media::VideoFrame::kUPlane);
- unsigned char* V = truth_frame->visible_data(media::VideoFrame::kVPlane);
- int32_t y_stride = truth_frame->stride(media::VideoFrame::kYPlane);
- int32_t u_stride = truth_frame->stride(media::VideoFrame::kUPlane);
- int32_t v_stride = truth_frame->stride(media::VideoFrame::kVPlane);
- memset(Y, 0x00, y_stride * output_ysize);
- memset(U, 0x80, u_stride * output_ysize / 2);
- memset(V, 0x80, v_stride * output_ysize / 2);
-
- const float kRGBtoYColorWeights[] = {0.257f, 0.504f, 0.098f, 0.0625f};
- const float kRGBtoUColorWeights[] = {-0.148f, -0.291f, 0.439f, 0.5f};
- const float kRGBtoVColorWeights[] = {0.439f, -0.368f, -0.071f, 0.5f};
-
- for (int y = 0; y < ysize; y++) {
- for (int x = 0; x < xsize; x++) {
- Y[(y + ymargin) * y_stride + x + xmargin] = float_to_byte(
- ChannelAsFloat(&input_pixels, x, y, 0) * kRGBtoYColorWeights[0] +
- ChannelAsFloat(&input_pixels, x, y, 1) * kRGBtoYColorWeights[1] +
- ChannelAsFloat(&input_pixels, x, y, 2) * kRGBtoYColorWeights[2] +
- kRGBtoYColorWeights[3]);
- }
- }
-
- for (int y = 0; y < ysize / 2; y++) {
- for (int x = 0; x < xsize / 2; x++) {
- U[(y + ymargin / 2) * u_stride + x + xmargin / 2] =
- float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
- kRGBtoUColorWeights[0] +
- Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
- kRGBtoUColorWeights[1] +
- Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
- kRGBtoUColorWeights[2] +
- kRGBtoUColorWeights[3]);
- V[(y + ymargin / 2) * v_stride + x + xmargin / 2] =
- float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
- kRGBtoVColorWeights[0] +
- Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
- kRGBtoVColorWeights[1] +
- Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
- kRGBtoVColorWeights[2] +
- kRGBtoVColorWeights[3]);
- }
- }
-
- ComparePlane(Y,
- y_stride,
- output_frame->visible_data(media::VideoFrame::kYPlane),
- output_frame->stride(media::VideoFrame::kYPlane),
- 2,
- output_xsize,
- output_ysize,
- &input_pixels,
- message + " Y plane");
- ComparePlane(U,
- u_stride,
- output_frame->visible_data(media::VideoFrame::kUPlane),
- output_frame->stride(media::VideoFrame::kUPlane),
- 2,
- output_xsize / 2,
- output_ysize / 2,
- &input_pixels,
- message + " U plane");
- ComparePlane(V,
- v_stride,
- output_frame->visible_data(media::VideoFrame::kVPlane),
- output_frame->stride(media::VideoFrame::kVPlane),
- 2,
- output_xsize / 2,
- output_ysize / 2,
- &input_pixels,
- message + " V plane");
-
- context_->deleteTexture(src_texture);
- }
-
- void TestAddOps(int src, int dst, bool scale_x, bool allow3) {
- std::deque<GLHelperScaling::ScaleOp> ops;
- GLHelperScaling::ScaleOp::AddOps(src, dst, scale_x, allow3, &ops);
- // Scale factor 3 is a special case.
- // It is currently only allowed by itself.
- if (allow3 && dst * 3 >= src && dst * 2 < src) {
- EXPECT_EQ(ops[0].scale_factor, 3);
- EXPECT_EQ(ops.size(), 1U);
- EXPECT_EQ(ops[0].scale_x, scale_x);
- EXPECT_EQ(ops[0].scale_size, dst);
- return;
- }
-
- for (size_t i = 0; i < ops.size(); i++) {
- EXPECT_EQ(ops[i].scale_x, scale_x);
- if (i == 0) {
- // Only the first op is allowed to be a scale up.
- // (Scaling up *after* scaling down would make it fuzzy.)
- EXPECT_TRUE(ops[0].scale_factor == 0 || ops[0].scale_factor == 2);
- } else {
- // All other operations must be 50% downscales.
- EXPECT_EQ(ops[i].scale_factor, 2);
- }
- }
- // Check that the scale factors make sense and add up.
- int tmp = dst;
- for (int i = static_cast<int>(ops.size() - 1); i >= 0; i--) {
- EXPECT_EQ(tmp, ops[i].scale_size);
- if (ops[i].scale_factor == 0) {
- EXPECT_EQ(i, 0);
- EXPECT_GT(tmp, src);
- tmp = src;
- } else {
- tmp *= ops[i].scale_factor;
- }
- }
- EXPECT_EQ(tmp, src);
- }
-
- void CheckPipeline2(int xsize,
- int ysize,
- int dst_xsize,
- int dst_ysize,
- const std::string& description) {
- std::vector<GLHelperScaling::ScalerStage> stages;
- helper_scaling_->ConvertScalerOpsToScalerStages(
- content::GLHelper::SCALER_QUALITY_GOOD,
- gfx::Size(xsize, ysize),
- gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(dst_xsize, dst_ysize),
- false,
- false,
- &x_ops_,
- &y_ops_,
- &stages);
- EXPECT_EQ(x_ops_.size(), 0U);
- EXPECT_EQ(y_ops_.size(), 0U);
- ValidateScalerStages(content::GLHelper::SCALER_QUALITY_GOOD,
- stages,
- gfx::Size(dst_xsize, dst_ysize),
- "");
- EXPECT_EQ(PrintStages(stages), description);
- }
-
- void CheckOptimizationsTest() {
- // Basic upscale. X and Y should be combined into one pass.
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 2000));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 2000));
- CheckPipeline2(1024, 768, 2000, 2000, "1024x768 -> 2000x2000 bilinear\n");
-
- // X scaled 1/2, Y upscaled, should still be one pass.
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 512));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 2000));
- CheckPipeline2(1024, 768, 512, 2000, "1024x768 -> 512x2000 bilinear\n");
-
- // X upscaled, Y scaled 1/2, one bilinear pass
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 2000));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 384));
- CheckPipeline2(1024, 768, 2000, 384, "1024x768 -> 2000x384 bilinear\n");
-
- // X scaled 1/2, Y scaled 1/2, one bilinear pass
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 512));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 384));
- CheckPipeline2(1024, 768, 512, 384, "1024x768 -> 512x384 bilinear\n");
-
- // X scaled 1/2, Y scaled to 60%, one bilinear2 pass.
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 50));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- CheckPipeline2(100, 100, 50, 60, "100x100 -> 50x60 bilinear2 Y\n");
-
- // X scaled to 60%, Y scaled 1/2, one bilinear2 pass.
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 120));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 50));
- CheckPipeline2(100, 100, 60, 50, "100x100 -> 60x50 bilinear2 X\n");
-
- // X scaled to 60%, Y scaled 60%, one bilinear2x2 pass.
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 120));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- CheckPipeline2(100, 100, 60, 60, "100x100 -> 60x60 bilinear2x2\n");
-
- // X scaled to 40%, Y scaled 40%, two bilinear3 passes.
- x_ops_.push_back(GLHelperScaling::ScaleOp(3, true, 40));
- y_ops_.push_back(GLHelperScaling::ScaleOp(3, false, 40));
- CheckPipeline2(100,
- 100,
- 40,
- 40,
- "100x100 -> 100x40 bilinear3 Y\n"
- "100x40 -> 40x40 bilinear3 X\n");
-
- // X scaled to 60%, Y scaled 40%
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 120));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(3, false, 40));
- CheckPipeline2(100,
- 100,
- 60,
- 40,
- "100x100 -> 100x40 bilinear3 Y\n"
- "100x40 -> 60x40 bilinear2 X\n");
-
- // X scaled to 40%, Y scaled 60%
- x_ops_.push_back(GLHelperScaling::ScaleOp(3, true, 40));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- CheckPipeline2(100,
- 100,
- 40,
- 60,
- "100x100 -> 100x60 bilinear2 Y\n"
- "100x60 -> 40x60 bilinear3 X\n");
-
- // X scaled to 30%, Y scaled 30%
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 120));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 60));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 30));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 30));
- CheckPipeline2(100,
- 100,
- 30,
- 30,
- "100x100 -> 100x30 bilinear4 Y\n"
- "100x30 -> 30x30 bilinear4 X\n");
-
- // X scaled to 50%, Y scaled 30%
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 50));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 30));
- CheckPipeline2(100, 100, 50, 30, "100x100 -> 50x30 bilinear4 Y\n");
-
- // X scaled to 150%, Y scaled 30%
- // Note that we avoid combinding X and Y passes
- // as that would probably be LESS efficient here.
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 150));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 120));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 60));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 30));
- CheckPipeline2(100,
- 100,
- 150,
- 30,
- "100x100 -> 100x30 bilinear4 Y\n"
- "100x30 -> 150x30 bilinear\n");
-
- // X scaled to 1%, Y scaled 1%
- x_ops_.push_back(GLHelperScaling::ScaleOp(0, true, 128));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 64));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 32));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 16));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 8));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 4));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 2));
- x_ops_.push_back(GLHelperScaling::ScaleOp(2, true, 1));
- y_ops_.push_back(GLHelperScaling::ScaleOp(0, false, 128));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 64));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 32));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 16));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 8));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 4));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 2));
- y_ops_.push_back(GLHelperScaling::ScaleOp(2, false, 1));
- CheckPipeline2(100,
- 100,
- 1,
- 1,
- "100x100 -> 100x32 bilinear4 Y\n"
- "100x32 -> 100x4 bilinear4 Y\n"
- "100x4 -> 64x1 bilinear2x2\n"
- "64x1 -> 8x1 bilinear4 X\n"
- "8x1 -> 1x1 bilinear4 X\n");
- }
-
- scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context_;
- gpu::ContextSupport* context_support_;
- scoped_ptr<content::GLHelper> helper_;
- scoped_ptr<content::GLHelperScaling> helper_scaling_;
- std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_;
-};
-
-class GLHelperPixelTest : public GLHelperTest {
- private:
- gfx::DisableNullDrawGLBindings enable_pixel_output_;
-};
-
-TEST_F(GLHelperTest, RGBASyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kRGBA_8888_SkColorType,
- false);
- EXPECT_EQ(result, true);
-}
-
-
-TEST_F(GLHelperTest, BGRASyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kBGRA_8888_SkColorType,
- false);
- EXPECT_EQ(result, true);
-}
-
-TEST_F(GLHelperTest, RGB565SyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kRGB_565_SkColorType,
- false);
- EXPECT_EQ(result, true);
-}
-
-TEST_F(GLHelperTest, RGBAASyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kRGBA_8888_SkColorType,
- true);
- EXPECT_EQ(result, true);
-}
-
-TEST_F(GLHelperTest, BGRAASyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kBGRA_8888_SkColorType,
- true);
- EXPECT_EQ(result, true);
-}
-
-TEST_F(GLHelperTest, RGB565ASyncReadbackTest) {
- const int kTestSize = 64;
- bool result = TestTextureFormatReadback(gfx::Size(kTestSize,kTestSize),
- kRGB_565_SkColorType,
- true);
- EXPECT_EQ(result, true);
-}
-
-TEST_F(GLHelperPixelTest, YUVReadbackOptTest) {
- // This test uses the gpu.service/gpu_decoder tracing events to detect how
- // many scaling passes are actually performed by the YUV readback pipeline.
- StartTracing(TRACE_DISABLED_BY_DEFAULT("gpu.service") ","
- TRACE_DISABLED_BY_DEFAULT("gpu_decoder"));
-
- TestYUVReadback(800,
- 400,
- 800,
- 400,
- 0,
- 0,
- 1,
- false,
- true,
- content::GLHelper::SCALER_QUALITY_FAST);
-
- std::map<std::string, int> event_counts;
- EndTracing(&event_counts);
- int draw_buffer_calls = event_counts["kDrawBuffersEXTImmediate"];
- int draw_arrays_calls = event_counts["kDrawArrays"];
- VLOG(1) << "Draw buffer calls: " << draw_buffer_calls;
- VLOG(1) << "DrawArrays calls: " << draw_arrays_calls;
-
- if (draw_buffer_calls) {
- // When using MRT, the YUV readback code should only
- // execute two draw arrays, and scaling should be integrated
- // into those two calls since we are using the FAST scalign
- // quality.
- EXPECT_EQ(2, draw_arrays_calls);
- } else {
- // When not using MRT, there are three passes for the YUV,
- // and one for the scaling.
- EXPECT_EQ(4, draw_arrays_calls);
- }
-}
-
-class GLHelperPixelYuvReadback :
- public GLHelperPixelTest,
- public ::testing::WithParamInterface<
- std::tr1::tuple<bool, bool, unsigned int, unsigned int>> {};
-
-int kYUVReadBackSizes[] = {2, 4, 14};
-
-TEST_P(GLHelperPixelYuvReadback, Test) {
- bool flip = std::tr1::get<0>(GetParam());
- bool use_mrt = std::tr1::get<1>(GetParam());
- unsigned int x = std::tr1::get<2>(GetParam());
- unsigned int y = std::tr1::get<3>(GetParam());
-
- for (unsigned int ox = x; ox < arraysize(kYUVReadBackSizes); ox++) {
- for (unsigned int oy = y; oy < arraysize(kYUVReadBackSizes); oy++) {
- // If output is a subsection of the destination frame, (letterbox)
- // then try different variations of where the subsection goes.
- for (Margin xm = x < ox ? MarginLeft : MarginRight;
- xm <= MarginRight;
- xm = NextMargin(xm)) {
- for (Margin ym = y < oy ? MarginLeft : MarginRight;
- ym <= MarginRight;
- ym = NextMargin(ym)) {
- for (int pattern = 0; pattern < 3; pattern++) {
- TestYUVReadback(kYUVReadBackSizes[x],
- kYUVReadBackSizes[y],
- kYUVReadBackSizes[ox],
- kYUVReadBackSizes[oy],
- compute_margin(kYUVReadBackSizes[x],
- kYUVReadBackSizes[ox], xm),
- compute_margin(kYUVReadBackSizes[y],
- kYUVReadBackSizes[oy], ym),
- pattern,
- flip,
- use_mrt,
- content::GLHelper::SCALER_QUALITY_GOOD);
- if (HasFailure()) {
- return;
- }
- }
- }
- }
- }
- }
-}
-
-// First argument is intentionally empty.
-INSTANTIATE_TEST_CASE_P(
- ,
- GLHelperPixelYuvReadback,
- ::testing::Combine(
- ::testing::Bool(),
- ::testing::Bool(),
- ::testing::Range<unsigned int>(0, arraysize(kYUVReadBackSizes)),
- ::testing::Range<unsigned int>(0, arraysize(kYUVReadBackSizes))));
-
-
-// Per pixel tests, all sizes are small so that we can print
-// out the generated bitmaps.
-TEST_F(GLHelperPixelTest, ScaleTest) {
- int sizes[] = {3, 6, 16};
- for (int flip = 0; flip <= 1; flip++) {
- for (size_t q_index = 0; q_index < arraysize(kQualities); q_index++) {
- for (int x = 0; x < 3; x++) {
- for (int y = 0; y < 3; y++) {
- for (int dst_x = 0; dst_x < 3; dst_x++) {
- for (int dst_y = 0; dst_y < 3; dst_y++) {
- for (int pattern = 0; pattern < 3; pattern++) {
- TestScale(sizes[x],
- sizes[y],
- sizes[dst_x],
- sizes[dst_y],
- pattern,
- q_index,
- flip == 1);
- if (HasFailure()) {
- return;
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-// Per pixel tests, all sizes are small so that we can print
-// out the generated bitmaps.
-TEST_F(GLHelperPixelTest, CropScaleReadbackAndCleanTextureTest) {
- const int kSizes[] = {3, 6, 16};
- const SkColorType kColorTypes[] = {
- kAlpha_8_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType};
- for (size_t color_type = 0; color_type < arraysize(kColorTypes);
- color_type++) {
- // Test BEST and FAST qualities, skip GOOD
- for (size_t q_index = 0; q_index < arraysize(kQualities); q_index += 2) {
- for (size_t x = 0; x < arraysize(kSizes); x++) {
- for (size_t y = 0; y < arraysize(kSizes); y++) {
- for (size_t dst_x = 0; dst_x < arraysize(kSizes); dst_x++) {
- for (size_t dst_y = 0; dst_y < arraysize(kSizes); dst_y++) {
- for (int pattern = 0; pattern < 3; pattern++) {
- TestCropScaleReadbackAndCleanTexture(kSizes[x],
- kSizes[y],
- kSizes[dst_x],
- kSizes[dst_y],
- pattern,
- kColorTypes[color_type],
- false,
- q_index);
- if (HasFailure())
- return;
- }
- }
- }
- }
- }
- }
- }
-}
-
-// Validate that all scaling generates valid pipelines.
-TEST_F(GLHelperTest, ValidateScalerPipelines) {
- int sizes[] = {7, 99, 128, 256, 512, 719, 720, 721, 1920, 2011, 3217, 4096};
- for (size_t q = 0; q < arraysize(kQualities); q++) {
- for (size_t x = 0; x < arraysize(sizes); x++) {
- for (size_t y = 0; y < arraysize(sizes); y++) {
- for (size_t dst_x = 0; dst_x < arraysize(sizes); dst_x++) {
- for (size_t dst_y = 0; dst_y < arraysize(sizes); dst_y++) {
- TestScalerPipeline(
- q, sizes[x], sizes[y], sizes[dst_x], sizes[dst_y]);
- if (HasFailure()) {
- return;
- }
- }
- }
- }
- }
- }
-}
-
-// Make sure we don't create overly complicated pipelines
-// for a few common use cases.
-TEST_F(GLHelperTest, CheckSpecificPipelines) {
- // Upscale should be single pass.
- CheckPipeline(content::GLHelper::SCALER_QUALITY_GOOD,
- 1024,
- 700,
- 1280,
- 720,
- "1024x700 -> 1280x720 bilinear\n");
- // Slight downscale should use BILINEAR2X2.
- CheckPipeline(content::GLHelper::SCALER_QUALITY_GOOD,
- 1280,
- 720,
- 1024,
- 700,
- "1280x720 -> 1024x700 bilinear2x2\n");
- // Most common tab capture pipeline on the Pixel.
- // Should be using two BILINEAR3 passes.
- CheckPipeline(content::GLHelper::SCALER_QUALITY_GOOD,
- 2560,
- 1476,
- 1249,
- 720,
- "2560x1476 -> 2560x720 bilinear3 Y\n"
- "2560x720 -> 1249x720 bilinear3 X\n");
-}
-
-TEST_F(GLHelperTest, ScalerOpTest) {
- for (int allow3 = 0; allow3 <= 1; allow3++) {
- for (int dst = 1; dst < 2049; dst += 1 + (dst >> 3)) {
- for (int src = 1; src < 2049; src++) {
- TestAddOps(src, dst, allow3 == 1, (src & 1) == 1);
- if (HasFailure()) {
- LOG(ERROR) << "Failed for src=" << src << " dst=" << dst
- << " allow3=" << allow3;
- return;
- }
- }
- }
- }
-}
-
-TEST_F(GLHelperTest, CheckOptimizations) {
- // Test in baseclass since it is friends with GLHelperScaling
- CheckOptimizationsTest();
-}
-
-} // namespace content
-
-namespace {
-
-int RunHelper(base::TestSuite* test_suite) {
- content::UnitTestTestSuite runner(test_suite);
- base::MessageLoopForIO message_loop;
- return runner.Run();
-}
-
-} // namespace
-
-// These tests needs to run against a proper GL environment, so we
-// need to set it up before we can run the tests.
-int main(int argc, char** argv) {
- base::CommandLine::Init(argc, argv);
- base::TestSuite* suite = new content::ContentTestSuite(argc, argv);
-#if defined(OS_MACOSX)
- base::mac::ScopedNSAutoreleasePool pool;
-#endif
-
- return base::LaunchUnitTestsSerially(
- argc,
- argv,
- base::Bind(&RunHelper, base::Unretained(suite)));
-}
diff --git a/chromium/content/common/gpu/client/gpu_channel_host.cc b/chromium/content/common/gpu/client/gpu_channel_host.cc
deleted file mode 100644
index 25328f45399..00000000000
--- a/chromium/content/common/gpu/client/gpu_channel_host.cc
+++ /dev/null
@@ -1,552 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/client/gpu_channel_host.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "base/atomic_sequence_num.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/command_buffer_proxy_impl.h"
-#include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ipc/ipc_sync_message_filter.h"
-#include "url/gurl.h"
-
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#include "content/public/common/sandbox_init.h"
-#endif
-
-using base::AutoLock;
-
-namespace content {
-namespace {
-
-// Global atomic to generate unique transfer buffer IDs.
-base::StaticAtomicSequenceNumber g_next_transfer_buffer_id;
-
-} // namespace
-
-GpuChannelHost::StreamFlushInfo::StreamFlushInfo()
- : next_stream_flush_id(1),
- flushed_stream_flush_id(0),
- verified_stream_flush_id(0),
- flush_pending(false),
- route_id(MSG_ROUTING_NONE),
- put_offset(0),
- flush_count(0),
- flush_id(0) {}
-
-GpuChannelHost::StreamFlushInfo::~StreamFlushInfo() {}
-
-// static
-scoped_refptr<GpuChannelHost> GpuChannelHost::Create(
- GpuChannelHostFactory* factory,
- int channel_id,
- const gpu::GPUInfo& gpu_info,
- const IPC::ChannelHandle& channel_handle,
- base::WaitableEvent* shutdown_event,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) {
- DCHECK(factory->IsMainThread());
- scoped_refptr<GpuChannelHost> host =
- new GpuChannelHost(factory, channel_id, gpu_info,
- gpu_memory_buffer_manager);
- host->Connect(channel_handle, shutdown_event);
- return host;
-}
-
-GpuChannelHost::GpuChannelHost(
- GpuChannelHostFactory* factory,
- int channel_id,
- const gpu::GPUInfo& gpu_info,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager)
- : factory_(factory),
- channel_id_(channel_id),
- gpu_info_(gpu_info),
- gpu_memory_buffer_manager_(gpu_memory_buffer_manager) {
- next_image_id_.GetNext();
- next_route_id_.GetNext();
- next_stream_id_.GetNext();
-}
-
-void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle,
- base::WaitableEvent* shutdown_event) {
- DCHECK(factory_->IsMainThread());
- // Open a channel to the GPU process. We pass NULL as the main listener here
- // since we need to filter everything to route it to the right thread.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- factory_->GetIOThreadTaskRunner();
- channel_ =
- IPC::SyncChannel::Create(channel_handle, IPC::Channel::MODE_CLIENT, NULL,
- io_task_runner.get(), true, shutdown_event);
-
- sync_filter_ = channel_->CreateSyncMessageFilter();
-
- channel_filter_ = new MessageFilter();
-
- // Install the filter last, because we intercept all leftover
- // messages.
- channel_->AddFilter(channel_filter_.get());
-}
-
-bool GpuChannelHost::Send(IPC::Message* msg) {
- // Callee takes ownership of message, regardless of whether Send is
- // successful. See IPC::Sender.
- scoped_ptr<IPC::Message> message(msg);
- // The GPU process never sends synchronous IPCs so clear the unblock flag to
- // preserve order.
- message->set_unblock(false);
-
- // Currently we need to choose between two different mechanisms for sending.
- // On the main thread we use the regular channel Send() method, on another
- // thread we use SyncMessageFilter. We also have to be careful interpreting
- // IsMainThread() since it might return false during shutdown,
- // impl we are actually calling from the main thread (discard message then).
- //
- // TODO: Can we just always use sync_filter_ since we setup the channel
- // without a main listener?
- if (factory_->IsMainThread()) {
- // channel_ is only modified on the main thread, so we don't need to take a
- // lock here.
- if (!channel_) {
- DVLOG(1) << "GpuChannelHost::Send failed: Channel already destroyed";
- return false;
- }
- // http://crbug.com/125264
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
- bool result = channel_->Send(message.release());
- if (!result)
- DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed";
- return result;
- }
-
- bool result = sync_filter_->Send(message.release());
- return result;
-}
-
-uint32_t GpuChannelHost::OrderingBarrier(
- int32_t route_id,
- int32_t stream_id,
- int32_t put_offset,
- uint32_t flush_count,
- const std::vector<ui::LatencyInfo>& latency_info,
- bool put_offset_changed,
- bool do_flush) {
- AutoLock lock(context_lock_);
- StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
- if (flush_info.flush_pending && flush_info.route_id != route_id)
- InternalFlush(&flush_info);
-
- if (put_offset_changed) {
- const uint32_t flush_id = flush_info.next_stream_flush_id++;
- flush_info.flush_pending = true;
- flush_info.route_id = route_id;
- flush_info.put_offset = put_offset;
- flush_info.flush_count = flush_count;
- flush_info.flush_id = flush_id;
- flush_info.latency_info.insert(flush_info.latency_info.end(),
- latency_info.begin(), latency_info.end());
-
- if (do_flush)
- InternalFlush(&flush_info);
-
- return flush_id;
- }
- return 0;
-}
-
-void GpuChannelHost::FlushPendingStream(int32_t stream_id) {
- AutoLock lock(context_lock_);
- auto flush_info_iter = stream_flush_info_.find(stream_id);
- if (flush_info_iter == stream_flush_info_.end())
- return;
-
- StreamFlushInfo& flush_info = flush_info_iter->second;
- if (flush_info.flush_pending)
- InternalFlush(&flush_info);
-}
-
-void GpuChannelHost::InternalFlush(StreamFlushInfo* flush_info) {
- context_lock_.AssertAcquired();
- DCHECK(flush_info);
- DCHECK(flush_info->flush_pending);
- DCHECK_LT(flush_info->flushed_stream_flush_id, flush_info->flush_id);
- Send(new GpuCommandBufferMsg_AsyncFlush(
- flush_info->route_id, flush_info->put_offset, flush_info->flush_count,
- flush_info->latency_info));
- flush_info->latency_info.clear();
- flush_info->flush_pending = false;
-
- flush_info->flushed_stream_flush_id = flush_info->flush_id;
-}
-
-scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateViewCommandBuffer(
- int32_t surface_id,
- CommandBufferProxyImpl* share_group,
- int32_t stream_id,
- GpuStreamPriority stream_priority,
- const std::vector<int32_t>& attribs,
- const GURL& active_url,
- gfx::GpuPreference gpu_preference) {
- DCHECK(!share_group || (stream_id == share_group->stream_id()));
- TRACE_EVENT1("gpu",
- "GpuChannelHost::CreateViewCommandBuffer",
- "surface_id",
- surface_id);
-
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id =
- share_group ? share_group->route_id() : MSG_ROUTING_NONE;
- init_params.stream_id = stream_id;
- init_params.stream_priority = stream_priority;
- init_params.attribs = attribs;
- init_params.active_url = active_url;
- init_params.gpu_preference = gpu_preference;
-
- int32_t route_id = GenerateRouteID();
-
- CreateCommandBufferResult result = factory_->CreateViewCommandBuffer(
- surface_id, init_params, route_id);
- if (result != CREATE_COMMAND_BUFFER_SUCCEEDED) {
- LOG(ERROR) << "GpuChannelHost::CreateViewCommandBuffer failed.";
-
- if (result == CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST) {
- // The GPU channel needs to be considered lost. The caller will
- // then set up a new connection, and the GPU channel and any
- // view command buffers will all be associated with the same GPU
- // process.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- factory_->GetIOThreadTaskRunner();
- io_task_runner->PostTask(
- FROM_HERE, base::Bind(&GpuChannelHost::MessageFilter::OnChannelError,
- channel_filter_.get()));
- }
-
- return NULL;
- }
-
- scoped_ptr<CommandBufferProxyImpl> command_buffer =
- make_scoped_ptr(new CommandBufferProxyImpl(this, route_id, stream_id));
- AddRoute(route_id, command_buffer->AsWeakPtr());
-
- return command_buffer;
-}
-
-scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateOffscreenCommandBuffer(
- const gfx::Size& size,
- CommandBufferProxyImpl* share_group,
- int32_t stream_id,
- GpuStreamPriority stream_priority,
- const std::vector<int32_t>& attribs,
- const GURL& active_url,
- gfx::GpuPreference gpu_preference) {
- DCHECK(!share_group || (stream_id == share_group->stream_id()));
- TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer");
-
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id =
- share_group ? share_group->route_id() : MSG_ROUTING_NONE;
- init_params.stream_id = stream_id;
- init_params.stream_priority = stream_priority;
- init_params.attribs = attribs;
- init_params.active_url = active_url;
- init_params.gpu_preference = gpu_preference;
-
- int32_t route_id = GenerateRouteID();
-
- bool succeeded = false;
- if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(
- size, init_params, route_id, &succeeded))) {
- LOG(ERROR) << "Failed to send GpuChannelMsg_CreateOffscreenCommandBuffer.";
- return NULL;
- }
-
- if (!succeeded) {
- LOG(ERROR)
- << "GpuChannelMsg_CreateOffscreenCommandBuffer returned failure.";
- return NULL;
- }
-
- scoped_ptr<CommandBufferProxyImpl> command_buffer =
- make_scoped_ptr(new CommandBufferProxyImpl(this, route_id, stream_id));
- AddRoute(route_id, command_buffer->AsWeakPtr());
-
- return command_buffer;
-}
-
-scoped_ptr<media::JpegDecodeAccelerator> GpuChannelHost::CreateJpegDecoder(
- media::JpegDecodeAccelerator::Client* client) {
- TRACE_EVENT0("gpu", "GpuChannelHost::CreateJpegDecoder");
-
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- factory_->GetIOThreadTaskRunner();
- int32_t route_id = GenerateRouteID();
- scoped_ptr<GpuJpegDecodeAcceleratorHost> decoder(
- new GpuJpegDecodeAcceleratorHost(this, route_id, io_task_runner));
- if (!decoder->Initialize(client)) {
- return nullptr;
- }
-
- // The reply message of jpeg decoder should run on IO thread.
- io_task_runner->PostTask(FROM_HERE,
- base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
- channel_filter_.get(), route_id,
- decoder->GetReceiver(), io_task_runner));
-
- return std::move(decoder);
-}
-
-void GpuChannelHost::DestroyCommandBuffer(
- CommandBufferProxyImpl* command_buffer) {
- TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer");
-
- int32_t route_id = command_buffer->route_id();
- int32_t stream_id = command_buffer->stream_id();
- Send(new GpuChannelMsg_DestroyCommandBuffer(route_id));
- RemoveRoute(route_id);
-
- AutoLock lock(context_lock_);
- StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
- if (flush_info.flush_pending && flush_info.route_id == route_id)
- flush_info.flush_pending = false;
-}
-
-void GpuChannelHost::DestroyChannel() {
- DCHECK(factory_->IsMainThread());
- AutoLock lock(context_lock_);
- channel_.reset();
-}
-
-void GpuChannelHost::AddRoute(
- int route_id, base::WeakPtr<IPC::Listener> listener) {
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- factory_->GetIOThreadTaskRunner();
- io_task_runner->PostTask(FROM_HERE,
- base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
- channel_filter_.get(), route_id, listener,
- base::ThreadTaskRunnerHandle::Get()));
-}
-
-void GpuChannelHost::RemoveRoute(int route_id) {
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- factory_->GetIOThreadTaskRunner();
- io_task_runner->PostTask(
- FROM_HERE, base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
- channel_filter_.get(), route_id));
-}
-
-base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
- base::SharedMemoryHandle source_handle) {
- if (IsLost())
- return base::SharedMemory::NULLHandle();
-
-#if defined(OS_WIN) || defined(OS_MACOSX)
- // Windows and Mac need to explicitly duplicate the handle out to another
- // process.
- base::SharedMemoryHandle target_handle;
- base::ProcessId peer_pid;
- {
- AutoLock lock(context_lock_);
- if (!channel_)
- return base::SharedMemory::NULLHandle();
- peer_pid = channel_->GetPeerPID();
- }
- bool success = BrokerDuplicateSharedMemoryHandle(source_handle, peer_pid,
- &target_handle);
- if (!success)
- return base::SharedMemory::NULLHandle();
-
- return target_handle;
-#else
- return base::SharedMemory::DuplicateHandle(source_handle);
-#endif // defined(OS_WIN) || defined(OS_MACOSX)
-}
-
-int32_t GpuChannelHost::ReserveTransferBufferId() {
- // 0 is a reserved value.
- return g_next_transfer_buffer_id.GetNext() + 1;
-}
-
-gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess(
- const gfx::GpuMemoryBufferHandle& source_handle,
- bool* requires_sync_point) {
- switch (source_handle.type) {
- case gfx::SHARED_MEMORY_BUFFER: {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SHARED_MEMORY_BUFFER;
- handle.handle = ShareToGpuProcess(source_handle.handle);
- handle.offset = source_handle.offset;
- handle.stride = source_handle.stride;
- *requires_sync_point = false;
- return handle;
- }
- case gfx::IO_SURFACE_BUFFER:
- case gfx::SURFACE_TEXTURE_BUFFER:
- case gfx::OZONE_NATIVE_PIXMAP:
- *requires_sync_point = true;
- return source_handle;
- default:
- NOTREACHED();
- return gfx::GpuMemoryBufferHandle();
- }
-}
-
-int32_t GpuChannelHost::ReserveImageId() {
- return next_image_id_.GetNext();
-}
-
-int32_t GpuChannelHost::GenerateRouteID() {
- return next_route_id_.GetNext();
-}
-
-int32_t GpuChannelHost::GenerateStreamID() {
- const int32_t stream_id = next_stream_id_.GetNext();
- DCHECK_NE(0, stream_id);
- DCHECK_NE(kDefaultStreamId, stream_id);
- return stream_id;
-}
-
-uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32_t stream_id,
- bool force_validate) {
- // Store what flush ids we will be validating for all streams.
- base::hash_map<int32_t, uint32_t> validate_flushes;
- uint32_t flushed_stream_flush_id = 0;
- uint32_t verified_stream_flush_id = 0;
- {
- AutoLock lock(context_lock_);
- for (const auto& iter : stream_flush_info_) {
- const int32_t iter_stream_id = iter.first;
- const StreamFlushInfo& flush_info = iter.second;
- if (iter_stream_id == stream_id) {
- flushed_stream_flush_id = flush_info.flushed_stream_flush_id;
- verified_stream_flush_id = flush_info.verified_stream_flush_id;
- }
-
- if (flush_info.flushed_stream_flush_id >
- flush_info.verified_stream_flush_id) {
- validate_flushes.insert(
- std::make_pair(iter_stream_id, flush_info.flushed_stream_flush_id));
- }
- }
- }
-
- if (!force_validate && flushed_stream_flush_id == verified_stream_flush_id) {
- // Current stream has no unverified flushes.
- return verified_stream_flush_id;
- }
-
- if (Send(new GpuChannelMsg_Nop())) {
- // Update verified flush id for all streams.
- uint32_t highest_flush_id = 0;
- AutoLock lock(context_lock_);
- for (const auto& iter : validate_flushes) {
- const int32_t validated_stream_id = iter.first;
- const uint32_t validated_flush_id = iter.second;
- StreamFlushInfo& flush_info = stream_flush_info_[validated_stream_id];
- if (flush_info.verified_stream_flush_id < validated_flush_id) {
- flush_info.verified_stream_flush_id = validated_flush_id;
- }
-
- if (validated_stream_id == stream_id)
- highest_flush_id = flush_info.verified_stream_flush_id;
- }
-
- return highest_flush_id;
- }
-
- return 0;
-}
-
-uint32_t GpuChannelHost::GetHighestValidatedFlushID(int32_t stream_id) {
- AutoLock lock(context_lock_);
- StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
- return flush_info.verified_stream_flush_id;
-}
-
-GpuChannelHost::~GpuChannelHost() {
-#if DCHECK_IS_ON()
- AutoLock lock(context_lock_);
- DCHECK(!channel_)
- << "GpuChannelHost::DestroyChannel must be called before destruction.";
-#endif
-}
-
-GpuChannelHost::MessageFilter::ListenerInfo::ListenerInfo() {}
-
-GpuChannelHost::MessageFilter::ListenerInfo::~ListenerInfo() {}
-
-GpuChannelHost::MessageFilter::MessageFilter()
- : lost_(false) {
-}
-
-GpuChannelHost::MessageFilter::~MessageFilter() {}
-
-void GpuChannelHost::MessageFilter::AddRoute(
- int32_t route_id,
- base::WeakPtr<IPC::Listener> listener,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(listeners_.find(route_id) == listeners_.end());
- DCHECK(task_runner);
- ListenerInfo info;
- info.listener = listener;
- info.task_runner = task_runner;
- listeners_[route_id] = info;
-}
-
-void GpuChannelHost::MessageFilter::RemoveRoute(int32_t route_id) {
- listeners_.erase(route_id);
-}
-
-bool GpuChannelHost::MessageFilter::OnMessageReceived(
- const IPC::Message& message) {
- // Never handle sync message replies or we will deadlock here.
- if (message.is_reply())
- return false;
-
- auto it = listeners_.find(message.routing_id());
- if (it == listeners_.end())
- return false;
-
- const ListenerInfo& info = it->second;
- info.task_runner->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&IPC::Listener::OnMessageReceived),
- info.listener, message));
- return true;
-}
-
-void GpuChannelHost::MessageFilter::OnChannelError() {
- // Set the lost state before signalling the proxies. That way, if they
- // themselves post a task to recreate the context, they will not try to re-use
- // this channel host.
- {
- AutoLock lock(lock_);
- lost_ = true;
- }
-
- // Inform all the proxies that an error has occurred. This will be reported
- // via OpenGL as a lost context.
- for (const auto& kv : listeners_) {
- const ListenerInfo& info = kv.second;
- info.task_runner->PostTask(
- FROM_HERE, base::Bind(&IPC::Listener::OnChannelError, info.listener));
- }
-
- listeners_.clear();
-}
-
-bool GpuChannelHost::MessageFilter::IsLost() const {
- AutoLock lock(lock_);
- return lost_;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_channel_host.h b/chromium/content/common/gpu/client/gpu_channel_host.h
deleted file mode 100644
index bf7b3894c21..00000000000
--- a/chromium/content/common/gpu/client/gpu_channel_host.h
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/atomic_sequence_num.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/process/process.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
-#include "content/common/gpu/gpu_result_codes.h"
-#include "content/common/gpu/gpu_stream_priority.h"
-#include "content/common/message_router.h"
-#include "gpu/config/gpu_info.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/ipc_sync_channel.h"
-#include "ipc/message_filter.h"
-#include "media/video/jpeg_decode_accelerator.h"
-#include "ui/events/latency_info.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gpu_preference.h"
-
-class GURL;
-class TransportTextureService;
-struct GPUCreateCommandBufferConfig;
-
-namespace base {
-class MessageLoop;
-class WaitableEvent;
-}
-
-namespace IPC {
-class SyncMessageFilter;
-}
-
-namespace media {
-class JpegDecodeAccelerator;
-class VideoDecodeAccelerator;
-class VideoEncodeAccelerator;
-}
-
-namespace gpu {
-class GpuMemoryBufferManager;
-}
-
-namespace content {
-class CommandBufferProxyImpl;
-class GpuChannelHost;
-
-class CONTENT_EXPORT GpuChannelHostFactory {
- public:
- virtual ~GpuChannelHostFactory() {}
-
- virtual bool IsMainThread() = 0;
- virtual scoped_refptr<base::SingleThreadTaskRunner>
- GetIOThreadTaskRunner() = 0;
- virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
- virtual CreateCommandBufferResult CreateViewCommandBuffer(
- int32_t surface_id,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id) = 0;
-};
-
-// Encapsulates an IPC channel between the client and one GPU process.
-// On the GPU process side there's a corresponding GpuChannel.
-// Every method can be called on any thread with a message loop, except for the
-// IO thread.
-class GpuChannelHost : public IPC::Sender,
- public base::RefCountedThreadSafe<GpuChannelHost> {
- public:
- // Must be called on the main thread (as defined by the factory).
- static scoped_refptr<GpuChannelHost> Create(
- GpuChannelHostFactory* factory,
- int channel_id,
- const gpu::GPUInfo& gpu_info,
- const IPC::ChannelHandle& channel_handle,
- base::WaitableEvent* shutdown_event,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
-
- static const int32_t kDefaultStreamId = -1;
- static const GpuStreamPriority kDefaultStreamPriority =
- GpuStreamPriority::NORMAL;
-
- bool IsLost() const {
- DCHECK(channel_filter_.get());
- return channel_filter_->IsLost();
- }
-
- int channel_id() const { return channel_id_; }
-
- // The GPU stats reported by the GPU process.
- const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* msg) override;
-
- // Set an ordering barrier. AsyncFlushes any pending barriers on other
- // routes. Combines multiple OrderingBarriers into a single AsyncFlush.
- // Returns the flush ID for the stream or 0 if put offset was not changed.
- uint32_t OrderingBarrier(int32_t route_id,
- int32_t stream_id,
- int32_t put_offset,
- uint32_t flush_count,
- const std::vector<ui::LatencyInfo>& latency_info,
- bool put_offset_changed,
- bool do_flush);
-
- void FlushPendingStream(int32_t stream_id);
-
- // Create and connect to a command buffer in the GPU process.
- scoped_ptr<CommandBufferProxyImpl> CreateViewCommandBuffer(
- int32_t surface_id,
- CommandBufferProxyImpl* share_group,
- int32_t stream_id,
- GpuStreamPriority stream_priority,
- const std::vector<int32_t>& attribs,
- const GURL& active_url,
- gfx::GpuPreference gpu_preference);
-
- // Create and connect to a command buffer in the GPU process.
- scoped_ptr<CommandBufferProxyImpl> CreateOffscreenCommandBuffer(
- const gfx::Size& size,
- CommandBufferProxyImpl* share_group,
- int32_t stream_id,
- GpuStreamPriority stream_priority,
- const std::vector<int32_t>& attribs,
- const GURL& active_url,
- gfx::GpuPreference gpu_preference);
-
- // Creates a JPEG decoder in the GPU process.
- scoped_ptr<media::JpegDecodeAccelerator> CreateJpegDecoder(
- media::JpegDecodeAccelerator::Client* client);
-
- // Destroy a command buffer created by this channel.
- void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer);
-
- // Destroy this channel. Must be called on the main thread, before
- // destruction.
- void DestroyChannel();
-
- // Add a route for the current message loop.
- void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener);
- void RemoveRoute(int route_id);
-
- GpuChannelHostFactory* factory() const { return factory_; }
-
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const {
- return gpu_memory_buffer_manager_;
- }
-
- // Returns a handle to the shared memory that can be sent via IPC to the
- // GPU process. The caller is responsible for ensuring it is closed. Returns
- // an invalid handle on failure.
- base::SharedMemoryHandle ShareToGpuProcess(
- base::SharedMemoryHandle source_handle);
-
- // Reserve one unused transfer buffer ID.
- int32_t ReserveTransferBufferId();
-
- // Returns a GPU memory buffer handle to the buffer that can be sent via
- // IPC to the GPU process. The caller is responsible for ensuring it is
- // closed. Returns an invalid handle on failure.
- gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuProcess(
- const gfx::GpuMemoryBufferHandle& source_handle,
- bool* requires_sync_point);
-
- // Reserve one unused image ID.
- int32_t ReserveImageId();
-
- // Generate a route ID guaranteed to be unique for this channel.
- int32_t GenerateRouteID();
-
- // Generate a stream ID guaranteed to be unique for this channel.
- int32_t GenerateStreamID();
-
- // Sends a synchronous nop to the server which validate that all previous IPC
- // messages have been received. Once the synchronous nop has been sent to the
- // server all previous flushes will all be marked as validated, including
- // flushes for other streams on the same channel. Once a validation has been
- // sent, it will return the highest validated flush id for the stream.
- // If the validation fails (which can only happen upon context lost), the
- // highest validated flush id will not change. If no flush ID were ever
- // validated then it will return 0 (Note the lowest valid flush ID is 1).
- uint32_t ValidateFlushIDReachedServer(int32_t stream_id, bool force_validate);
-
- // Returns the highest validated flush ID for a given stream.
- uint32_t GetHighestValidatedFlushID(int32_t stream_id);
-
- private:
- friend class base::RefCountedThreadSafe<GpuChannelHost>;
-
- // A filter used internally to route incoming messages from the IO thread
- // to the correct message loop. It also maintains some shared state between
- // all the contexts.
- class MessageFilter : public IPC::MessageFilter {
- public:
- MessageFilter();
-
- // Called on the IO thread.
- void AddRoute(int32_t route_id,
- base::WeakPtr<IPC::Listener> listener,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- // Called on the IO thread.
- void RemoveRoute(int32_t route_id);
-
- // IPC::MessageFilter implementation
- // (called on the IO thread):
- bool OnMessageReceived(const IPC::Message& msg) override;
- void OnChannelError() override;
-
- // The following methods can be called on any thread.
-
- // Whether the channel is lost.
- bool IsLost() const;
-
- private:
- struct ListenerInfo {
- ListenerInfo();
- ~ListenerInfo();
-
- base::WeakPtr<IPC::Listener> listener;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner;
- };
-
- ~MessageFilter() override;
-
- // Threading notes: |listeners_| is only accessed on the IO thread. Every
- // other field is protected by |lock_|.
- base::hash_map<int32_t, ListenerInfo> listeners_;
-
- // Protects all fields below this one.
- mutable base::Lock lock_;
-
- // Whether the channel has been lost.
- bool lost_;
- };
-
- struct StreamFlushInfo {
- StreamFlushInfo();
- ~StreamFlushInfo();
-
- // These are global per stream.
- uint32_t next_stream_flush_id;
- uint32_t flushed_stream_flush_id;
- uint32_t verified_stream_flush_id;
-
- // These are local per context.
- bool flush_pending;
- int32_t route_id;
- int32_t put_offset;
- uint32_t flush_count;
- uint32_t flush_id;
- std::vector<ui::LatencyInfo> latency_info;
- };
-
- GpuChannelHost(GpuChannelHostFactory* factory,
- int channel_id,
- const gpu::GPUInfo& gpu_info,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
- ~GpuChannelHost() override;
- void Connect(const IPC::ChannelHandle& channel_handle,
- base::WaitableEvent* shutdown_event);
- bool InternalSend(IPC::Message* msg);
- void InternalFlush(StreamFlushInfo* flush_info);
-
- // Threading notes: all fields are constant during the lifetime of |this|
- // except:
- // - |next_image_id_|, atomic type
- // - |next_route_id_|, atomic type
- // - |next_stream_id_|, atomic type
- // - |channel_| and |stream_flush_info_|, protected by |context_lock_|
- GpuChannelHostFactory* const factory_;
-
- const int channel_id_;
- const gpu::GPUInfo gpu_info_;
-
- scoped_refptr<MessageFilter> channel_filter_;
-
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
-
- // A filter for sending messages from thread other than the main thread.
- scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
-
- // Image IDs are allocated in sequence.
- base::AtomicSequenceNumber next_image_id_;
-
- // Route IDs are allocated in sequence.
- base::AtomicSequenceNumber next_route_id_;
-
- // Stream IDs are allocated in sequence.
- base::AtomicSequenceNumber next_stream_id_;
-
- // Protects channel_ and stream_flush_info_.
- mutable base::Lock context_lock_;
- scoped_ptr<IPC::SyncChannel> channel_;
- base::hash_map<int32_t, StreamFlushInfo> stream_flush_info_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
diff --git a/chromium/content/common/gpu/client/gpu_context_tests.h b/chromium/content/common/gpu/client/gpu_context_tests.h
index 8810789d076..9687c4a057e 100644
--- a/chromium/content/common/gpu/client/gpu_context_tests.h
+++ b/chromium/content/common/gpu/client/gpu_context_tests.h
@@ -10,6 +10,7 @@
#include "base/run_loop.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/sync_token.h"
namespace {
@@ -30,32 +31,39 @@ class SignalTest : public ContextTestBase {
}
// These tests should time out if the callback doesn't get called.
- void TestSignalQuery(blink::WebGLId query) {
+ void TestSignalQuery(GLuint query) {
base::RunLoop run_loop;
context_support_->SignalQuery(
- query,
- base::Bind(
- &RunOnlyOnce, run_loop.QuitClosure(), base::Owned(new int(0))));
+ query, base::Bind(&RunOnlyOnce, run_loop.QuitClosure(),
+ base::Owned(new int(0))));
run_loop.Run();
}
};
CONTEXT_TEST_F(SignalTest, BasicSignalSyncTokenTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
- const blink::WGC3Duint64 fence_sync = context_->insertFenceSyncCHROMIUM();
- context_->shallowFlushCHROMIUM();
+ const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM();
+ gl_->ShallowFlushCHROMIUM();
gpu::SyncToken sync_token;
- ASSERT_TRUE(context_->genSyncTokenCHROMIUM(fence_sync, sync_token.GetData()));
+ gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
TestSignalSyncToken(sync_token);
};
CONTEXT_TEST_F(SignalTest, EmptySignalSyncTokenTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
// Signalling something that doesn't exist should run the callback
// immediately.
@@ -64,42 +72,59 @@ CONTEXT_TEST_F(SignalTest, EmptySignalSyncTokenTest) {
};
CONTEXT_TEST_F(SignalTest, InvalidSignalSyncTokenTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
// Signalling something that doesn't exist should run the callback
// immediately.
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
- 0,
- 1297824234,
+ gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0,
+ gpu::CommandBufferId::FromUnsafeValue(1297824234),
9123743439);
TestSignalSyncToken(sync_token);
};
CONTEXT_TEST_F(SignalTest, BasicSignalQueryTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
- unsigned query = context_->createQueryEXT();
- context_->beginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query);
- context_->finish();
- context_->endQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
+ unsigned query;
+ gl_->GenQueriesEXT(1, &query);
+ gl_->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query);
+ gl_->Finish();
+ gl_->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
TestSignalQuery(query);
- context_->deleteQueryEXT(query);
+ gl_->DeleteQueriesEXT(1, &query);
};
CONTEXT_TEST_F(SignalTest, SignalQueryUnboundTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
- blink::WebGLId query = context_->createQueryEXT();
+ GLuint query;
+ gl_->GenQueriesEXT(1, &query);
TestSignalQuery(query);
- context_->deleteQueryEXT(query);
+ gl_->DeleteQueriesEXT(1, &query);
};
CONTEXT_TEST_F(SignalTest, InvalidSignalQueryUnboundTest) {
- if (!context_)
+#if defined(OS_WIN)
+ // The IPC version of ContextTestBase::SetUpOnMainThread does not succeed on
+ // some platforms.
+ if (!gl_)
return;
+#endif
// Signalling something that doesn't exist should run the callback
// immediately.
@@ -110,5 +135,4 @@ CONTEXT_TEST_F(SignalTest, InvalidSignalQueryUnboundTest) {
TestSignalQuery(928729082);
TestSignalQuery(928729081);
};
-
};
diff --git a/chromium/content/common/gpu/client/gpu_in_process_context_tests.cc b/chromium/content/common/gpu/client/gpu_in_process_context_tests.cc
index 6e740572211..c8f0d3f293f 100644
--- a/chromium/content/common/gpu/client/gpu_in_process_context_tests.cc
+++ b/chromium/content/common/gpu/client/gpu_in_process_context_tests.cc
@@ -7,32 +7,50 @@
#include <string>
#include <vector>
-#include "content/public/test/unittest_test_suite.h"
-#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
+#include "gpu/command_buffer/client/gl_in_process_context.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_surface.h"
namespace {
-using gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl;
-
class ContextTestBase : public testing::Test {
public:
void SetUp() override {
- blink::WebGraphicsContext3D::Attributes attributes;
- bool lose_context_when_out_of_memory = false;
- typedef WebGraphicsContext3DInProcessCommandBufferImpl WGC3DIPCBI;
- context_ = WGC3DIPCBI::CreateOffscreenContext(
- attributes, lose_context_when_out_of_memory);
- context_->InitializeOnCurrentThread();
- context_support_ = context_->GetContextSupport();
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = 8;
+ attributes.depth_size = 24;
+ attributes.red_size = 8;
+ attributes.green_size = 8;
+ attributes.blue_size = 8;
+ attributes.stencil_size = 8;
+ attributes.samples = 4;
+ attributes.sample_buffers = 1;
+ attributes.bind_generates_resource = false;
+
+ context_.reset(gpu::GLInProcessContext::Create(
+ nullptr, /* service */
+ nullptr, /* surface */
+ true, /* offscreen */
+ gfx::kNullAcceleratedWidget, /* window */
+ gfx::Size(1, 1), /* size */
+ nullptr, /* share_context */
+ attributes, gfx::PreferDiscreteGpu,
+ ::gpu::GLInProcessContextSharedMemoryLimits(),
+ nullptr, /* gpu_memory_buffer_manager */
+ nullptr /* image_factory */));
+ gl_ = context_->GetImplementation();
+ context_support_ = context_->GetImplementation();
}
void TearDown() override { context_.reset(NULL); }
protected:
- scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context_;
+ gpu::gles2::GLES2Interface* gl_;
gpu::ContextSupport* context_support_;
+
+ private:
+ scoped_ptr<gpu::GLInProcessContext> context_;
};
} // namespace
diff --git a/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc b/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc
deleted file mode 100644
index eac971b43b7..00000000000
--- a/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h"
-
-#include <stddef.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory_handle.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/waitable_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_utils.h"
-
-namespace content {
-
-// Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
-// thread. This does very similar what MessageFilter usually does. It is not
-// MessageFilter because GpuChannelHost doesn't support AddFilter.
-class GpuJpegDecodeAcceleratorHost::Receiver : public IPC::Listener,
- public base::NonThreadSafe {
- public:
- Receiver(Client* client,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
- : client_(client),
- io_task_runner_(io_task_runner),
- weak_factory_for_io_(this) {
- DCHECK(CalledOnValidThread());
- }
-
- ~Receiver() override { DCHECK(CalledOnValidThread()); }
-
- void InvalidateWeakPtr(base::WaitableEvent* event) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- weak_factory_for_io_.InvalidateWeakPtrs();
- event->Signal();
- }
-
- // IPC::Listener implementation.
- void OnChannelError() override {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- OnDecodeAck(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
- }
-
- bool OnMessageReceived(const IPC::Message& msg) override {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost::Receiver, msg)
- IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled);
- return handled;
- }
-
- base::WeakPtr<IPC::Listener> AsWeakPtrForIO() {
- return weak_factory_for_io_.GetWeakPtr();
- }
-
- private:
- void OnDecodeAck(int32_t bitstream_buffer_id, Error error) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!client_)
- return;
-
- if (error == media::JpegDecodeAccelerator::NO_ERRORS) {
- client_->VideoFrameReady(bitstream_buffer_id);
- } else {
- // Only NotifyError once.
- // Client::NotifyError() may trigger deletion of |this| (on another
- // thread), so calling it needs to be the last thing done on this stack!
- media::JpegDecodeAccelerator::Client* client = nullptr;
- std::swap(client, client_);
- client->NotifyError(bitstream_buffer_id, error);
- }
- }
-
- Client* client_;
-
- // GPU IO task runner.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- // Weak pointers will be invalidated on IO thread.
- base::WeakPtrFactory<Receiver> weak_factory_for_io_;
-
- DISALLOW_COPY_AND_ASSIGN(Receiver);
-};
-
-GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
- GpuChannelHost* channel,
- int32_t route_id,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
- : channel_(channel),
- decoder_route_id_(route_id),
- io_task_runner_(io_task_runner) {
- DCHECK(channel_);
- DCHECK_NE(decoder_route_id_, MSG_ROUTING_NONE);
-}
-
-GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
- DCHECK(CalledOnValidThread());
- Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_));
-
- if (receiver_) {
- channel_->RemoveRoute(decoder_route_id_);
-
- // Invalidate weak ptr of |receiver_|. After that, no more messages will be
- // routed to |receiver_| on IO thread.
- base::WaitableEvent event(false, false);
- io_task_runner_->PostTask(FROM_HERE,
- base::Bind(&Receiver::InvalidateWeakPtr,
- base::Unretained(receiver_.get()),
- base::Unretained(&event)));
- event.Wait();
- }
-}
-
-bool GpuJpegDecodeAcceleratorHost::Initialize(
- media::JpegDecodeAccelerator::Client* client) {
- DCHECK(CalledOnValidThread());
-
- bool succeeded = false;
- // This cannot be on IO thread because the msg is synchronous.
- Send(new GpuMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
-
- if (!succeeded) {
- DLOG(ERROR) << "Send(GpuMsg_CreateJpegDecoder()) failed";
- return false;
- }
-
- receiver_.reset(new Receiver(client, io_task_runner_));
-
- return true;
-}
-
-void GpuJpegDecodeAcceleratorHost::Decode(
- const media::BitstreamBuffer& bitstream_buffer,
- const scoped_refptr<media::VideoFrame>& video_frame) {
- DCHECK(CalledOnValidThread());
-
- DCHECK(
- base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle()));
-
- base::SharedMemoryHandle input_handle =
- channel_->ShareToGpuProcess(bitstream_buffer.handle());
- if (!base::SharedMemory::IsHandleValid(input_handle)) {
- DLOG(ERROR) << "Failed to duplicate handle of BitstreamBuffer";
- return;
- }
- base::SharedMemoryHandle output_handle =
- channel_->ShareToGpuProcess(video_frame->shared_memory_handle());
- if (!base::SharedMemory::IsHandleValid(output_handle)) {
- DLOG(ERROR) << "Failed to duplicate handle of VideoFrame";
-#if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
- if (input_handle.auto_close) {
- // Defer closing task to the ScopedFD.
- base::ScopedFD(input_handle.fd);
- }
-#else
- // TODO(kcwu) fix the handle leak after crbug.com/493414 resolved.
-#endif
- return;
- }
-
- size_t output_buffer_size = media::VideoFrame::AllocationSize(
- video_frame->format(), video_frame->coded_size());
-
- AcceleratedJpegDecoderMsg_Decode_Params decode_params;
- decode_params.coded_size = video_frame->coded_size();
- decode_params.input_buffer_id = bitstream_buffer.id();
- decode_params.input_buffer_handle = input_handle;
- decode_params.input_buffer_size = bitstream_buffer.size();
- decode_params.output_video_frame_handle = output_handle;
- decode_params.output_buffer_size = output_buffer_size;
- Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params));
-}
-
-bool GpuJpegDecodeAcceleratorHost::IsSupported() {
- return channel_->gpu_info().jpeg_decode_accelerator_supported;
-}
-
-void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
- DCHECK(CalledOnValidThread());
-
- if (!channel_->Send(message)) {
- DLOG(ERROR) << "Send(" << message->type() << ") failed";
- }
-}
-
-base::WeakPtr<IPC::Listener> GpuJpegDecodeAcceleratorHost::GetReceiver() {
- return receiver_->AsWeakPtrForIO();
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h b/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h
deleted file mode 100644
index 53465f3aee7..00000000000
--- a/chromium/content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_GPU_CLIENT_GPU_JPEG_DECODE_ACCELERATOR_HOST_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_JPEG_DECODE_ACCELERATOR_HOST_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "media/video/jpeg_decode_accelerator.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace IPC {
-class Listener;
-class Message;
-}
-
-namespace content {
-class GpuChannelHost;
-
-// This class is used to talk to JpegDecodeAccelerator in the GPU process
-// through IPC messages.
-class GpuJpegDecodeAcceleratorHost : public media::JpegDecodeAccelerator,
- public base::NonThreadSafe {
- public:
- // VideoCaptureGpuJpegDecoder owns |this| and |channel|. And
- // VideoCaptureGpuJpegDecoder delete |this| before |channel|. So |this| is
- // guaranteed not to outlive |channel|.
- GpuJpegDecodeAcceleratorHost(
- GpuChannelHost* channel,
- int32_t route_id,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
- ~GpuJpegDecodeAcceleratorHost() override;
-
- // media::JpegDecodeAccelerator implementation.
- // |client| is called on the IO thread, but is never called into after the
- // GpuJpegDecodeAcceleratorHost is destroyed.
- bool Initialize(media::JpegDecodeAccelerator::Client* client) override;
- void Decode(const media::BitstreamBuffer& bitstream_buffer,
- const scoped_refptr<media::VideoFrame>& video_frame) override;
- bool IsSupported() override;
-
- base::WeakPtr<IPC::Listener> GetReceiver();
-
- private:
- class Receiver;
-
- void Send(IPC::Message* message);
-
- // Unowned reference to the GpuChannelHost to send IPC messages to the GPU
- // process.
- GpuChannelHost* channel_;
-
- // Route ID for the associated decoder in the GPU process.
- int32_t decoder_route_id_;
-
- // GPU IO task runner.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- scoped_ptr<Receiver> receiver_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuJpegDecodeAcceleratorHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_JPEG_DECODE_ACCELERATOR_HOST_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl.cc
deleted file mode 100644
index 5c6571aaf66..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2013 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 "content/common/gpu/client/gpu_memory_buffer_impl.h"
-
-#include "base/logging.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
-
-#if defined(OS_MACOSX)
-#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
-#endif
-
-#if defined(OS_ANDROID)
-#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
-#endif
-
-#if defined(USE_OZONE)
-#include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h"
-#endif
-
-namespace content {
-
-GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback)
- : id_(id),
- size_(size),
- format_(format),
- callback_(callback),
- mapped_(false) {}
-
-GpuMemoryBufferImpl::~GpuMemoryBufferImpl() {
- DCHECK(!mapped_);
- callback_.Run(destruction_sync_token_);
-}
-
-// static
-scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback) {
- switch (handle.type) {
- case gfx::SHARED_MEMORY_BUFFER:
- return GpuMemoryBufferImplSharedMemory::CreateFromHandle(
- handle, size, format, usage, callback);
-#if defined(OS_MACOSX)
- case gfx::IO_SURFACE_BUFFER:
- return GpuMemoryBufferImplIOSurface::CreateFromHandle(
- handle, size, format, usage, callback);
-#endif
-#if defined(OS_ANDROID)
- case gfx::SURFACE_TEXTURE_BUFFER:
- return GpuMemoryBufferImplSurfaceTexture::CreateFromHandle(
- handle, size, format, usage, callback);
-#endif
-#if defined(USE_OZONE)
- case gfx::OZONE_NATIVE_PIXMAP:
- return GpuMemoryBufferImplOzoneNativePixmap::CreateFromHandle(
- handle, size, format, usage, callback);
-#endif
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-// static
-GpuMemoryBufferImpl* GpuMemoryBufferImpl::FromClientBuffer(
- ClientBuffer buffer) {
- return reinterpret_cast<GpuMemoryBufferImpl*>(buffer);
-}
-
-gfx::Size GpuMemoryBufferImpl::GetSize() const {
- return size_;
-}
-
-gfx::BufferFormat GpuMemoryBufferImpl::GetFormat() const {
- return format_;
-}
-
-gfx::GpuMemoryBufferId GpuMemoryBufferImpl::GetId() const {
- return id_;
-}
-
-ClientBuffer GpuMemoryBufferImpl::AsClientBuffer() {
- return reinterpret_cast<ClientBuffer>(this);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl.h b/chromium/content/common/gpu/client/gpu_memory_buffer_impl.h
deleted file mode 100644
index 954a87535fd..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2013 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 CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/common/content_export.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace content {
-
-// Provides common implementation of a GPU memory buffer.
-class CONTENT_EXPORT GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
- public:
- typedef base::Callback<void(const gpu::SyncToken& sync)> DestructionCallback;
-
- ~GpuMemoryBufferImpl() override;
-
- // Creates an instance from the given |handle|. |size| and |internalformat|
- // should match what was used to allocate the |handle|. |callback| is
- // called when instance is deleted, which is not necessarily on the same
- // thread as this function was called on and instance was created on.
- static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback);
-
- // Type-checking upcast routine. Returns an NULL on failure.
- static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer);
-
- // Overridden from gfx::GpuMemoryBuffer:
- gfx::Size GetSize() const override;
- gfx::BufferFormat GetFormat() const override;
- gfx::GpuMemoryBufferId GetId() const override;
- ClientBuffer AsClientBuffer() override;
-
- void set_destruction_sync_token(const gpu::SyncToken& sync_token) {
- destruction_sync_token_ = sync_token;
- }
-
- protected:
- GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback);
-
- const gfx::GpuMemoryBufferId id_;
- const gfx::Size size_;
- const gfx::BufferFormat format_;
- const DestructionCallback callback_;
- bool mapped_;
- gpu::SyncToken destruction_sync_token_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
deleted file mode 100644
index b6038cf72da..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2013 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 "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
-
-#include "base/logging.h"
-#include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gfx/mac/io_surface.h"
-
-namespace content {
-namespace {
-
-uint32_t LockFlags(gfx::BufferUsage usage) {
- switch (usage) {
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- return kIOSurfaceLockAvoidSync;
- case gfx::BufferUsage::GPU_READ:
- case gfx::BufferUsage::SCANOUT:
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
- return 0;
- }
- NOTREACHED();
- return 0;
-}
-
-void NoOp() {
-}
-
-} // namespace
-
-GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- IOSurfaceRef io_surface,
- uint32_t lock_flags)
- : GpuMemoryBufferImpl(id, size, format, callback),
- io_surface_(io_surface),
- lock_flags_(lock_flags) {}
-
-GpuMemoryBufferImplIOSurface::~GpuMemoryBufferImplIOSurface() {
-}
-
-// static
-scoped_ptr<GpuMemoryBufferImplIOSurface>
-GpuMemoryBufferImplIOSurface::CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback) {
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
- IOSurfaceLookupFromMachPort(handle.mach_port.get()));
- if (!io_surface)
- return nullptr;
-
- return make_scoped_ptr(
- new GpuMemoryBufferImplIOSurface(handle.id, size, format, callback,
- io_surface.release(), LockFlags(usage)));
-}
-
-// static
-bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- return GpuMemoryBufferFactoryIOSurface::
- IsGpuMemoryBufferConfigurationSupported(format, usage);
-}
-
-// static
-base::Closure GpuMemoryBufferImplIOSurface::AllocateForTesting(
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle) {
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
- gfx::CreateIOSurface(size, format));
- DCHECK(io_surface);
- gfx::GpuMemoryBufferId kBufferId(1);
- handle->type = gfx::IO_SURFACE_BUFFER;
- handle->id = kBufferId;
- handle->mach_port.reset(IOSurfaceCreateMachPort(io_surface));
- return base::Bind(&NoOp);
-}
-
-bool GpuMemoryBufferImplIOSurface::Map() {
- DCHECK(!mapped_);
- IOReturn status = IOSurfaceLock(io_surface_, lock_flags_, NULL);
- DCHECK_NE(status, kIOReturnCannotLock);
- mapped_ = true;
- return true;
-}
-
-void* GpuMemoryBufferImplIOSurface::memory(size_t plane) {
- DCHECK(mapped_);
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- return IOSurfaceGetBaseAddressOfPlane(io_surface_, plane);
-}
-
-void GpuMemoryBufferImplIOSurface::Unmap() {
- DCHECK(mapped_);
- IOSurfaceUnlock(io_surface_, lock_flags_, NULL);
- mapped_ = false;
-}
-
-bool GpuMemoryBufferImplIOSurface::IsInUseByMacOSWindowServer() const {
- return IOSurfaceIsInUse(io_surface_);
-}
-
-int GpuMemoryBufferImplIOSurface::stride(size_t plane) const {
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- return IOSurfaceGetBytesPerRowOfPlane(io_surface_, plane);
-}
-
-gfx::GpuMemoryBufferHandle GpuMemoryBufferImplIOSurface::GetHandle() const {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::IO_SURFACE_BUFFER;
- handle.id = id_;
- return handle;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
deleted file mode 100644
index 8883cc1a3e2..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013 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 CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_IO_SURFACE_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_IO_SURFACE_H_
-
-#include <IOSurface/IOSurface.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-
-namespace content {
-
-// Implementation of GPU memory buffer based on IO surfaces.
-class CONTENT_EXPORT GpuMemoryBufferImplIOSurface : public GpuMemoryBufferImpl {
- public:
- ~GpuMemoryBufferImplIOSurface() override;
-
- static scoped_ptr<GpuMemoryBufferImplIOSurface> CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback);
-
- static bool IsConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- static base::Closure AllocateForTesting(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle);
-
- // Overridden from gfx::GpuMemoryBuffer:
- bool Map() override;
- void* memory(size_t plane) override;
- void Unmap() override;
- bool IsInUseByMacOSWindowServer() const override;
- int stride(size_t plane) const override;
- gfx::GpuMemoryBufferHandle GetHandle() const override;
-
- private:
- GpuMemoryBufferImplIOSurface(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- IOSurfaceRef io_surface,
- uint32_t lock_flags);
-
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
- uint32_t lock_flags_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplIOSurface);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_IO_SURFACE_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc
deleted file mode 100644
index 83edce6c3e7..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
-#include "content/test/gpu_memory_buffer_impl_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplIOSurface,
- GpuMemoryBufferImplTest,
- GpuMemoryBufferImplIOSurface);
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc
deleted file mode 100644
index c0303555ad9..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h"
-
-#include <utility>
-
-#include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/ozone/public/client_native_pixmap_factory.h"
-#include "ui/ozone/public/native_pixmap.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
-
-namespace content {
-namespace {
-
-void FreeNativePixmapForTesting(scoped_refptr<ui::NativePixmap> native_pixmap) {
- // Nothing to do here. |native_pixmap| will be freed when this function
- // returns and reference count drops to 0.
-}
-
-} // namespace
-
-GpuMemoryBufferImplOzoneNativePixmap::GpuMemoryBufferImplOzoneNativePixmap(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- scoped_ptr<ui::ClientNativePixmap> pixmap)
- : GpuMemoryBufferImpl(id, size, format, callback),
- pixmap_(std::move(pixmap)) {}
-
-GpuMemoryBufferImplOzoneNativePixmap::~GpuMemoryBufferImplOzoneNativePixmap() {}
-
-// static
-scoped_ptr<GpuMemoryBufferImplOzoneNativePixmap>
-GpuMemoryBufferImplOzoneNativePixmap::CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback) {
- scoped_ptr<ui::ClientNativePixmap> native_pixmap =
- ui::ClientNativePixmapFactory::GetInstance()->ImportFromHandle(
- handle.native_pixmap_handle, size, usage);
- DCHECK(native_pixmap);
- return make_scoped_ptr(new GpuMemoryBufferImplOzoneNativePixmap(
- handle.id, size, format, callback, std::move(native_pixmap)));
-}
-
-// static
-bool GpuMemoryBufferImplOzoneNativePixmap::IsConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- return GpuMemoryBufferFactoryOzoneNativePixmap::
- IsGpuMemoryBufferConfigurationSupported(format, usage);
-}
-
-// static
-base::Closure GpuMemoryBufferImplOzoneNativePixmap::AllocateForTesting(
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle) {
- DCHECK(IsConfigurationSupported(format, usage));
- scoped_refptr<ui::NativePixmap> pixmap =
- ui::OzonePlatform::GetInstance()
- ->GetSurfaceFactoryOzone()
- ->CreateNativePixmap(gfx::kNullPluginWindow, size, format, usage);
- handle->type = gfx::OZONE_NATIVE_PIXMAP;
- handle->native_pixmap_handle = pixmap->ExportHandle();
- return base::Bind(&FreeNativePixmapForTesting, pixmap);
-}
-
-bool GpuMemoryBufferImplOzoneNativePixmap::Map() {
- DCHECK(!mapped_);
- if (!pixmap_->Map())
- return false;
- mapped_ = true;
- return mapped_;
-}
-
-void* GpuMemoryBufferImplOzoneNativePixmap::memory(size_t plane) {
- DCHECK(mapped_);
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- return pixmap_->Map();
-}
-
-void GpuMemoryBufferImplOzoneNativePixmap::Unmap() {
- DCHECK(mapped_);
- pixmap_->Unmap();
- mapped_ = false;
-}
-
-int GpuMemoryBufferImplOzoneNativePixmap::stride(size_t plane) const {
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- int stride;
- pixmap_->GetStride(&stride);
- return stride;
-}
-
-gfx::GpuMemoryBufferHandle GpuMemoryBufferImplOzoneNativePixmap::GetHandle()
- const {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::OZONE_NATIVE_PIXMAP;
- handle.id = id_;
- return handle;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h
deleted file mode 100644
index aa073e111e3..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_NATIVE_PIXMAP_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_NATIVE_PIXMAP_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-
-namespace ui {
-class ClientNativePixmap;
-}
-
-namespace content {
-
-// Implementation of GPU memory buffer based on Ozone native pixmap.
-class CONTENT_EXPORT GpuMemoryBufferImplOzoneNativePixmap
- : public GpuMemoryBufferImpl {
- public:
- ~GpuMemoryBufferImplOzoneNativePixmap() override;
-
- static scoped_ptr<GpuMemoryBufferImplOzoneNativePixmap> CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback);
-
- static bool IsConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- static base::Closure AllocateForTesting(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle);
-
- // Overridden from gfx::GpuMemoryBuffer:
- bool Map() override;
- void* memory(size_t plane) override;
- void Unmap() override;
- int stride(size_t plane) const override;
- gfx::GpuMemoryBufferHandle GetHandle() const override;
-
- private:
- GpuMemoryBufferImplOzoneNativePixmap(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- scoped_ptr<ui::ClientNativePixmap> native_pixmap);
-
- scoped_ptr<ui::ClientNativePixmap> pixmap_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplOzoneNativePixmap);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_NATIVE_PIXMAP_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc
deleted file mode 100644
index 08295c5186e..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h"
-#include "content/test/gpu_memory_buffer_impl_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplOzoneNativePixmap,
- GpuMemoryBufferImplTest,
- GpuMemoryBufferImplOzoneNativePixmap);
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
deleted file mode 100644
index 83781ae8553..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
-
-#include <stdint.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/numerics/safe_math.h"
-#include "base/process/memory.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gl/gl_bindings.h"
-
-namespace content {
-namespace {
-
-void Noop() {}
-
-} // namespace
-
-GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- scoped_ptr<base::SharedMemory> shared_memory,
- size_t offset,
- int stride)
- : GpuMemoryBufferImpl(id, size, format, callback),
- shared_memory_(std::move(shared_memory)),
- offset_(offset),
- stride_(stride) {
- DCHECK(IsSizeValidForFormat(size, format));
-}
-
-GpuMemoryBufferImplSharedMemory::~GpuMemoryBufferImplSharedMemory() {
-}
-
-// static
-scoped_ptr<GpuMemoryBufferImplSharedMemory>
-GpuMemoryBufferImplSharedMemory::Create(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback) {
- size_t buffer_size = 0u;
- if (!gfx::BufferSizeForBufferFormatChecked(size, format, &buffer_size))
- return nullptr;
-
- scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
- if (!shared_memory->CreateAndMapAnonymous(buffer_size))
- return nullptr;
-
- return make_scoped_ptr(new GpuMemoryBufferImplSharedMemory(
- id, size, format, callback, std::move(shared_memory), 0,
- gfx::RowSizeForBufferFormat(size.width(), format, 0)));
-}
-
-// static
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- base::ProcessHandle child_process) {
- size_t buffer_size = 0u;
- if (!gfx::BufferSizeForBufferFormatChecked(size, format, &buffer_size))
- return gfx::GpuMemoryBufferHandle();
-
- base::SharedMemory shared_memory;
- if (!shared_memory.CreateAnonymous(buffer_size))
- return gfx::GpuMemoryBufferHandle();
-
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SHARED_MEMORY_BUFFER;
- handle.id = id;
- handle.offset = 0;
- handle.stride = static_cast<int32_t>(
- gfx::RowSizeForBufferFormat(size.width(), format, 0));
- shared_memory.GiveToProcess(child_process, &handle.handle);
- return handle;
-}
-
-// static
-scoped_ptr<GpuMemoryBufferImplSharedMemory>
-GpuMemoryBufferImplSharedMemory::CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback) {
- DCHECK(base::SharedMemory::IsHandleValid(handle.handle));
-
- return make_scoped_ptr(new GpuMemoryBufferImplSharedMemory(
- handle.id, size, format, callback,
- make_scoped_ptr(new base::SharedMemory(handle.handle, false)),
- handle.offset, handle.stride));
-}
-
-// static
-bool GpuMemoryBufferImplSharedMemory::IsUsageSupported(gfx::BufferUsage usage) {
- switch (usage) {
- case gfx::BufferUsage::GPU_READ:
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
- return true;
- case gfx::BufferUsage::SCANOUT:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
-// static
-bool GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- return IsUsageSupported(usage);
-}
-
-// static
-bool GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(
- const gfx::Size& size,
- gfx::BufferFormat format) {
- switch (format) {
- case gfx::BufferFormat::ATC:
- case gfx::BufferFormat::ATCIA:
- case gfx::BufferFormat::DXT1:
- case gfx::BufferFormat::DXT5:
- case gfx::BufferFormat::ETC1:
- // Compressed images must have a width and height that's evenly divisible
- // by the block size.
- return size.width() % 4 == 0 && size.height() % 4 == 0;
- case gfx::BufferFormat::R_8:
- case gfx::BufferFormat::RGBA_4444:
- case gfx::BufferFormat::RGBA_8888:
- case gfx::BufferFormat::RGBX_8888:
- case gfx::BufferFormat::BGRA_8888:
- case gfx::BufferFormat::BGRX_8888:
- return true;
- case gfx::BufferFormat::YUV_420:
- case gfx::BufferFormat::YUV_420_BIPLANAR: {
- size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format);
- for (size_t i = 0; i < num_planes; ++i) {
- size_t factor = gfx::SubsamplingFactorForBufferFormat(format, i);
- if (size.width() % factor || size.height() % factor)
- return false;
- }
- return true;
- }
- case gfx::BufferFormat::UYVY_422:
- return size.width() % 2 == 0;
- }
-
- NOTREACHED();
- return false;
-}
-
-// static
-base::Closure GpuMemoryBufferImplSharedMemory::AllocateForTesting(
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle) {
- base::SharedMemory shared_memory;
- bool rv = shared_memory.CreateAnonymous(
- gfx::BufferSizeForBufferFormat(size, format));
- DCHECK(rv);
- handle->type = gfx::SHARED_MEMORY_BUFFER;
- handle->offset = 0;
- handle->stride = static_cast<int32_t>(
- gfx::RowSizeForBufferFormat(size.width(), format, 0));
- handle->handle = base::SharedMemory::DuplicateHandle(shared_memory.handle());
- return base::Bind(&Noop);
-}
-
-bool GpuMemoryBufferImplSharedMemory::Map() {
- DCHECK(!mapped_);
-
- // Map the buffer first time Map() is called then keep it mapped for the
- // lifetime of the buffer. This avoids mapping the buffer unless necessary.
- if (!shared_memory_->memory()) {
- DCHECK_EQ(static_cast<size_t>(stride_),
- gfx::RowSizeForBufferFormat(size_.width(), format_, 0));
- size_t buffer_size = gfx::BufferSizeForBufferFormat(size_, format_);
- // Note: offset_ != 0 is not common use-case. To keep it simple we
- // map offset + buffer_size here but this can be avoided using MapAt().
- size_t map_size = offset_ + buffer_size;
- if (!shared_memory_->Map(map_size))
- base::TerminateBecauseOutOfMemory(map_size);
- }
- mapped_ = true;
- return true;
-}
-
-void* GpuMemoryBufferImplSharedMemory::memory(size_t plane) {
- DCHECK(mapped_);
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- return reinterpret_cast<uint8_t*>(shared_memory_->memory()) + offset_ +
- gfx::BufferOffsetForBufferFormat(size_, format_, plane);
-}
-
-void GpuMemoryBufferImplSharedMemory::Unmap() {
- DCHECK(mapped_);
- mapped_ = false;
-}
-
-int GpuMemoryBufferImplSharedMemory::stride(size_t plane) const {
- DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_));
- return gfx::RowSizeForBufferFormat(size_.width(), format_, plane);
-}
-
-gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSharedMemory::GetHandle() const {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SHARED_MEMORY_BUFFER;
- handle.id = id_;
- handle.offset = offset_;
- handle.stride = stride_;
- handle.handle = shared_memory_->handle();
- return handle;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h
deleted file mode 100644
index 9416cbb31e1..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SHARED_MEMORY_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SHARED_MEMORY_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-
-namespace content {
-
-// Implementation of GPU memory buffer based on shared memory.
-class CONTENT_EXPORT GpuMemoryBufferImplSharedMemory
- : public GpuMemoryBufferImpl {
- public:
- ~GpuMemoryBufferImplSharedMemory() override;
-
- static scoped_ptr<GpuMemoryBufferImplSharedMemory> Create(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback);
-
- static gfx::GpuMemoryBufferHandle AllocateForChildProcess(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- base::ProcessHandle child_process);
-
- static scoped_ptr<GpuMemoryBufferImplSharedMemory> CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback);
-
- static bool IsUsageSupported(gfx::BufferUsage usage);
- static bool IsConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
- static bool IsSizeValidForFormat(const gfx::Size& size,
- gfx::BufferFormat format);
-
- static base::Closure AllocateForTesting(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle);
-
- // Overridden from gfx::GpuMemoryBuffer:
- bool Map() override;
- void* memory(size_t plane) override;
- void Unmap() override;
- int stride(size_t plane) const override;
- gfx::GpuMemoryBufferHandle GetHandle() const override;
-
- private:
- GpuMemoryBufferImplSharedMemory(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- scoped_ptr<base::SharedMemory> shared_memory,
- size_t offset,
- int stride);
-
- scoped_ptr<base::SharedMemory> shared_memory_;
- size_t offset_;
- int stride_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplSharedMemory);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SHARED_MEMORY_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
deleted file mode 100644
index 251e16c4a3a..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
-#include "content/test/gpu_memory_buffer_impl_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSharedMemory,
- GpuMemoryBufferImplTest,
- GpuMemoryBufferImplSharedMemory);
-
-void BufferDestroyed(bool* destroyed, const gpu::SyncToken& sync_token) {
- *destroyed = true;
-}
-
-TEST(GpuMemoryBufferImplSharedMemoryTest, Create) {
- const gfx::GpuMemoryBufferId kBufferId(1);
-
- gfx::Size buffer_size(8, 8);
-
- for (auto format : gfx::GetBufferFormatsForTesting()) {
- bool destroyed = false;
- scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer(
- GpuMemoryBufferImplSharedMemory::Create(
- kBufferId, buffer_size, format,
- base::Bind(&BufferDestroyed, base::Unretained(&destroyed))));
- ASSERT_TRUE(buffer);
- EXPECT_EQ(buffer->GetFormat(), format);
-
- // Check if destruction callback is executed when deleting the buffer.
- buffer.reset();
- ASSERT_TRUE(destroyed);
- }
-}
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
deleted file mode 100644
index 64de624c155..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/android/surface_texture_manager.h"
-#include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gl/android/surface_texture.h"
-#include "ui/gl/gl_bindings.h"
-
-namespace content {
-namespace {
-
-int WindowFormat(gfx::BufferFormat format) {
- switch (format) {
- case gfx::BufferFormat::RGBA_8888:
- return WINDOW_FORMAT_RGBA_8888;
- case gfx::BufferFormat::ATC:
- case gfx::BufferFormat::ATCIA:
- case gfx::BufferFormat::DXT1:
- case gfx::BufferFormat::DXT5:
- case gfx::BufferFormat::ETC1:
- case gfx::BufferFormat::R_8:
- case gfx::BufferFormat::RGBA_4444:
- case gfx::BufferFormat::RGBX_8888:
- case gfx::BufferFormat::BGRX_8888:
- case gfx::BufferFormat::BGRA_8888:
- case gfx::BufferFormat::YUV_420:
- case gfx::BufferFormat::YUV_420_BIPLANAR:
- case gfx::BufferFormat::UYVY_422:
- NOTREACHED();
- return 0;
- }
-
- NOTREACHED();
- return 0;
-}
-
-void FreeSurfaceTextureForTesting(
- scoped_refptr<gfx::SurfaceTexture> surface_texture,
- gfx::GpuMemoryBufferId id) {
- SurfaceTextureManager::GetInstance()->UnregisterSurfaceTexture(id.id, 0);
-}
-
-} // namespace
-
-GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- ANativeWindow* native_window)
- : GpuMemoryBufferImpl(id, size, format, callback),
- native_window_(native_window) {}
-
-GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
- ANativeWindow_release(native_window_);
-}
-
-// static
-scoped_ptr<GpuMemoryBufferImplSurfaceTexture>
-GpuMemoryBufferImplSurfaceTexture::CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback) {
- ANativeWindow* native_window =
- SurfaceTextureManager::GetInstance()
- ->AcquireNativeWidgetForSurfaceTexture(handle.id.id);
- if (!native_window)
- return nullptr;
-
- ANativeWindow_setBuffersGeometry(
- native_window, size.width(), size.height(), WindowFormat(format));
-
- return make_scoped_ptr(new GpuMemoryBufferImplSurfaceTexture(
- handle.id, size, format, callback, native_window));
-}
-
-// static
-bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- return GpuMemoryBufferFactorySurfaceTexture::
- IsGpuMemoryBufferConfigurationSupported(format, usage);
-}
-
-// static
-base::Closure GpuMemoryBufferImplSurfaceTexture::AllocateForTesting(
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle) {
- scoped_refptr<gfx::SurfaceTexture> surface_texture =
- gfx::SurfaceTexture::Create(0);
- DCHECK(surface_texture);
- const gfx::GpuMemoryBufferId kBufferId(1);
- SurfaceTextureManager::GetInstance()->RegisterSurfaceTexture(
- kBufferId.id, 0, surface_texture.get());
- handle->type = gfx::SURFACE_TEXTURE_BUFFER;
- handle->id = kBufferId;
- return base::Bind(&FreeSurfaceTextureForTesting, surface_texture, kBufferId);
-}
-
-bool GpuMemoryBufferImplSurfaceTexture::Map() {
- TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Map");
- DCHECK(!mapped_);
- DCHECK(native_window_);
- if (ANativeWindow_lock(native_window_, &buffer_, NULL)) {
- DPLOG(ERROR) << "ANativeWindow_lock failed";
- return false;
- }
- DCHECK_LE(size_.width(), buffer_.stride);
- mapped_ = true;
- return true;
-}
-
-void* GpuMemoryBufferImplSurfaceTexture::memory(size_t plane) {
- TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::memory");
- DCHECK(mapped_);
- DCHECK_EQ(0u, plane);
- return buffer_.bits;
-}
-
-void GpuMemoryBufferImplSurfaceTexture::Unmap() {
- TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap");
- DCHECK(mapped_);
- ANativeWindow_unlockAndPost(native_window_);
- mapped_ = false;
-}
-
-int GpuMemoryBufferImplSurfaceTexture::stride(size_t plane) const {
- DCHECK(mapped_);
- DCHECK_EQ(0u, plane);
- return gfx::RowSizeForBufferFormat(buffer_.stride, format_, 0);
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferImplSurfaceTexture::GetHandle() const {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SURFACE_TEXTURE_BUFFER;
- handle.id = id_;
- return handle;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
deleted file mode 100644
index 1613c63134b..00000000000
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SURFACE_TEXTURE_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SURFACE_TEXTURE_H_
-
-#include <android/native_window.h>
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-
-namespace content {
-
-// Implementation of GPU memory buffer based on SurfaceTextures.
-class CONTENT_EXPORT GpuMemoryBufferImplSurfaceTexture
- : public GpuMemoryBufferImpl {
- public:
- ~GpuMemoryBufferImplSurfaceTexture() override;
-
- static scoped_ptr<GpuMemoryBufferImplSurfaceTexture> CreateFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- const DestructionCallback& callback);
-
- static bool IsConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- static base::Closure AllocateForTesting(const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- gfx::GpuMemoryBufferHandle* handle);
-
- // Overridden from gfx::GpuMemoryBuffer:
- bool Map() override;
- void* memory(size_t plane) override;
- void Unmap() override;
- int stride(size_t plane) const override;
- gfx::GpuMemoryBufferHandle GetHandle() const override;
-
- private:
- GpuMemoryBufferImplSurfaceTexture(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- const DestructionCallback& callback,
- ANativeWindow* native_window);
-
- ANativeWindow* native_window_;
- ANativeWindow_Buffer buffer_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplSurfaceTexture);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SURFACE_TEXTURE_H_
diff --git a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc
index 1cd513df3ac..a3edc70bd8b 100644
--- a/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc
+++ b/chromium/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
-#include "content/test/gpu_memory_buffer_impl_test_template.h"
+#include "gpu/ipc/client/gpu_memory_buffer_impl_surface_texture.h"
+#include "gpu/ipc/client/gpu_memory_buffer_impl_test_template.h"
-namespace content {
+namespace gpu {
namespace {
INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSurfaceTexture,
@@ -13,4 +13,4 @@ INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSurfaceTexture,
GpuMemoryBufferImplSurfaceTexture);
} // namespace
-} // namespace content
+} // namespace gpu
diff --git a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
deleted file mode 100644
index 19a336b9ca3..00000000000
--- a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "build/build_config.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/view_messages.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_utils.h"
-
-#if defined(OS_WIN)
-#include "content/public/common/sandbox_init.h"
-#endif // OS_WIN
-
-using media::VideoDecodeAccelerator;
-namespace content {
-
-GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
- GpuChannelHost* channel,
- CommandBufferProxyImpl* impl)
- : channel_(channel),
- decoder_route_id_(MSG_ROUTING_NONE),
- client_(NULL),
- impl_(impl),
- weak_this_factory_(this) {
- DCHECK(channel_);
- DCHECK(impl_);
- impl_->AddDeletionObserver(this);
-}
-
-GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
- DCHECK(CalledOnValidThread());
-
- if (channel_ && decoder_route_id_ != MSG_ROUTING_NONE)
- channel_->RemoveRoute(decoder_route_id_);
- if (impl_)
- impl_->RemoveDeletionObserver(this);
-}
-
-bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
- DCHECK(CalledOnValidThread());
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CdmAttached,
- OnCdmAttached)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
- OnBitstreamBufferProcessed)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
- OnProvidePictureBuffer)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady,
- OnPictureReady)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone,
- OnFlushDone)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
- OnResetDone)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
- OnNotifyError)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
- OnDismissPictureBuffer)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled);
- // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
- // have been called above.
- return handled;
-}
-
-void GpuVideoDecodeAcceleratorHost::OnChannelError() {
- DCHECK(CalledOnValidThread());
- if (channel_) {
- if (decoder_route_id_ != MSG_ROUTING_NONE)
- channel_->RemoveRoute(decoder_route_id_);
- channel_ = NULL;
- }
- DLOG(ERROR) << "OnChannelError()";
- PostNotifyError(PLATFORM_FAILURE);
-}
-
-bool GpuVideoDecodeAcceleratorHost::Initialize(const Config& config,
- Client* client) {
- DCHECK(CalledOnValidThread());
- client_ = client;
-
- if (!impl_)
- return false;
-
- int32_t route_id = channel_->GenerateRouteID();
- channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr());
-
- bool succeeded = false;
- Send(new GpuCommandBufferMsg_CreateVideoDecoder(impl_->route_id(), config,
- route_id, &succeeded));
-
- if (!succeeded) {
- DLOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder()) failed";
- PostNotifyError(PLATFORM_FAILURE);
- channel_->RemoveRoute(route_id);
- return false;
- }
- decoder_route_id_ = route_id;
- return true;
-}
-
-void GpuVideoDecodeAcceleratorHost::SetCdm(int cdm_id) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
- Send(new AcceleratedVideoDecoderMsg_SetCdm(decoder_route_id_, cdm_id));
-}
-
-void GpuVideoDecodeAcceleratorHost::Decode(
- const media::BitstreamBuffer& bitstream_buffer) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
-
- base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
- bitstream_buffer.handle());
- if (!base::SharedMemory::IsHandleValid(handle)) {
- NOTREACHED() << "Failed to duplicate buffer handler";
- return;
- }
-
- AcceleratedVideoDecoderMsg_Decode_Params params;
- params.bitstream_buffer_id = bitstream_buffer.id();
- params.buffer_handle = handle;
- params.size = bitstream_buffer.size();
- params.presentation_timestamp = bitstream_buffer.presentation_timestamp();
- params.key_id = bitstream_buffer.key_id();
- params.iv = bitstream_buffer.iv();
- params.subsamples = bitstream_buffer.subsamples();
-
- Send(new AcceleratedVideoDecoderMsg_Decode(decoder_route_id_, params));
-}
-
-void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers(
- const std::vector<media::PictureBuffer>& buffers) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
- // Rearrange data for IPC command.
- std::vector<int32_t> buffer_ids;
- std::vector<uint32_t> texture_ids;
- for (uint32_t i = 0; i < buffers.size(); i++) {
- const media::PictureBuffer& buffer = buffers[i];
- if (buffer.size() != picture_buffer_dimensions_) {
- DLOG(ERROR) << "buffer.size() invalid: expected "
- << picture_buffer_dimensions_.ToString()
- << ", got " << buffer.size().ToString();
- PostNotifyError(INVALID_ARGUMENT);
- return;
- }
- texture_ids.push_back(buffer.texture_id());
- buffer_ids.push_back(buffer.id());
- }
- Send(new AcceleratedVideoDecoderMsg_AssignPictureBuffers(
- decoder_route_id_, buffer_ids, texture_ids));
-}
-
-void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
- int32_t picture_buffer_id) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
- Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
- decoder_route_id_, picture_buffer_id));
-}
-
-void GpuVideoDecodeAcceleratorHost::Flush() {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
- Send(new AcceleratedVideoDecoderMsg_Flush(decoder_route_id_));
-}
-
-void GpuVideoDecodeAcceleratorHost::Reset() {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
- Send(new AcceleratedVideoDecoderMsg_Reset(decoder_route_id_));
-}
-
-void GpuVideoDecodeAcceleratorHost::Destroy() {
- DCHECK(CalledOnValidThread());
- if (channel_)
- Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
- client_ = NULL;
- delete this;
-}
-
-void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
- DCHECK(CalledOnValidThread());
- impl_ = NULL;
-
- // The CommandBufferProxyImpl is going away; error out this VDA.
- OnChannelError();
-}
-
-void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) {
- DCHECK(CalledOnValidThread());
- DVLOG(2) << "PostNotifyError(): error=" << error;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&GpuVideoDecodeAcceleratorHost::OnNotifyError,
- weak_this_factory_.GetWeakPtr(), error));
-}
-
-void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
- DCHECK(CalledOnValidThread());
- uint32_t message_type = message->type();
- if (!channel_->Send(message)) {
- DLOG(ERROR) << "Send(" << message_type << ") failed";
- PostNotifyError(PLATFORM_FAILURE);
- }
-}
-
-void GpuVideoDecodeAcceleratorHost::OnCdmAttached(bool success) {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->NotifyCdmAttached(success);
-}
-
-void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
- int32_t bitstream_buffer_id) {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
-}
-
-void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
- uint32_t num_requested_buffers,
- const gfx::Size& dimensions,
- uint32_t texture_target) {
- DCHECK(CalledOnValidThread());
- picture_buffer_dimensions_ = dimensions;
- if (client_) {
- client_->ProvidePictureBuffers(
- num_requested_buffers, dimensions, texture_target);
- }
-}
-
-void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
- int32_t picture_buffer_id) {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->DismissPictureBuffer(picture_buffer_id);
-}
-
-void GpuVideoDecodeAcceleratorHost::OnPictureReady(
- int32_t picture_buffer_id,
- int32_t bitstream_buffer_id,
- const gfx::Rect& visible_rect,
- bool allow_overlay) {
- DCHECK(CalledOnValidThread());
- if (!client_)
- return;
- media::Picture picture(picture_buffer_id, bitstream_buffer_id, visible_rect,
- allow_overlay);
- client_->PictureReady(picture);
-}
-
-void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->NotifyFlushDone();
-}
-
-void GpuVideoDecodeAcceleratorHost::OnResetDone() {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->NotifyResetDone();
-}
-
-void GpuVideoDecodeAcceleratorHost::OnNotifyError(uint32_t error) {
- DCHECK(CalledOnValidThread());
- if (!client_)
- return;
- weak_this_factory_.InvalidateWeakPtrs();
-
- // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
- // last thing done on this stack!
- media::VideoDecodeAccelerator::Client* client = NULL;
- std::swap(client, client_);
- client->NotifyError(static_cast<media::VideoDecodeAccelerator::Error>(error));
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.h b/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.h
deleted file mode 100644
index 5e4ba9df1f6..00000000000
--- a/chromium/content/common/gpu/client/gpu_video_decode_accelerator_host.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "content/common/gpu/client/command_buffer_proxy_impl.h"
-#include "ipc/ipc_listener.h"
-#include "media/video/video_decode_accelerator.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-class GpuChannelHost;
-
-// This class is used to talk to VideoDecodeAccelerator in the Gpu process
-// through IPC messages.
-class GpuVideoDecodeAcceleratorHost
- : public IPC::Listener,
- public media::VideoDecodeAccelerator,
- public CommandBufferProxyImpl::DeletionObserver,
- public base::NonThreadSafe {
- public:
- // |this| is guaranteed not to outlive |channel| and |impl|. (See comments
- // for |channel_| and |impl_|.)
- GpuVideoDecodeAcceleratorHost(GpuChannelHost* channel,
- CommandBufferProxyImpl* impl);
-
- // IPC::Listener implementation.
- void OnChannelError() override;
- bool OnMessageReceived(const IPC::Message& message) override;
-
- // media::VideoDecodeAccelerator implementation.
- bool Initialize(const Config& config, Client* client) override;
- void SetCdm(int cdm_id) override;
- void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
- void AssignPictureBuffers(
- const std::vector<media::PictureBuffer>& buffers) override;
- void ReusePictureBuffer(int32_t picture_buffer_id) override;
- void Flush() override;
- void Reset() override;
- void Destroy() override;
-
- // CommandBufferProxyImpl::DeletionObserver implemetnation.
- void OnWillDeleteImpl() override;
-
- private:
- // Only Destroy() should be deleting |this|.
- ~GpuVideoDecodeAcceleratorHost() override;
-
- // Notify |client_| of an error. Posts a task to avoid re-entrancy.
- void PostNotifyError(Error);
-
- void Send(IPC::Message* message);
-
- // IPC handlers, proxying media::VideoDecodeAccelerator::Client for the GPU
- // process. Should not be called directly.
- void OnCdmAttached(bool success);
- void OnBitstreamBufferProcessed(int32_t bitstream_buffer_id);
- void OnProvidePictureBuffer(uint32_t num_requested_buffers,
- const gfx::Size& dimensions,
- uint32_t texture_target);
- void OnDismissPictureBuffer(int32_t picture_buffer_id);
- void OnPictureReady(int32_t picture_buffer_id,
- int32_t bitstream_buffer_id,
- const gfx::Rect& visible_rect,
- bool allow_overlay);
- void OnFlushDone();
- void OnResetDone();
- void OnNotifyError(uint32_t error);
-
- // Unowned reference to the GpuChannelHost to send IPC messages to the GPU
- // process. |channel_| outlives |impl_|, so the reference is always valid as
- // long as it is not NULL.
- GpuChannelHost* channel_;
-
- // Route ID for the associated decoder in the GPU process.
- int32_t decoder_route_id_;
-
- // The client that will receive callbacks from the decoder.
- Client* client_;
-
- // Unowned reference to the CommandBufferProxyImpl that created us. |this|
- // registers as a DeletionObserver of |impl_|, the so reference is always
- // valid as long as it is not NULL.
- CommandBufferProxyImpl* impl_;
-
- // Requested dimensions of the buffer, from ProvidePictureBuffers().
- gfx::Size picture_buffer_dimensions_;
-
- // WeakPtr factory for posting tasks back to itself.
- base::WeakPtrFactory<GpuVideoDecodeAcceleratorHost> weak_this_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuVideoDecodeAcceleratorHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_
diff --git a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc b/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc
deleted file mode 100644
index 9002490e1dd..00000000000
--- a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2013 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 "content/common/gpu/client/gpu_video_encode_accelerator_host.h"
-
-#include "base/location.h"
-#include "base/logging.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/media/gpu_video_accelerator_util.h"
-#include "media/base/video_frame.h"
-#include "media/video/video_encode_accelerator.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace content {
-
-GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost(
- GpuChannelHost* channel,
- CommandBufferProxyImpl* impl)
- : channel_(channel),
- encoder_route_id_(MSG_ROUTING_NONE),
- client_(NULL),
- impl_(impl),
- next_frame_id_(0),
- weak_this_factory_(this) {
- DCHECK(channel_);
- DCHECK(impl_);
- impl_->AddDeletionObserver(this);
-}
-
-GpuVideoEncodeAcceleratorHost::~GpuVideoEncodeAcceleratorHost() {
- DCHECK(CalledOnValidThread());
- if (channel_ && encoder_route_id_ != MSG_ROUTING_NONE)
- channel_->RemoveRoute(encoder_route_id_);
- if (impl_)
- impl_->RemoveDeletionObserver(this);
-}
-
-bool GpuVideoEncodeAcceleratorHost::OnMessageReceived(
- const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAcceleratorHost, message)
- IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers,
- OnRequireBitstreamBuffers)
- IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInputDone,
- OnNotifyInputDone)
- IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady,
- OnBitstreamBufferReady)
- IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyError,
- OnNotifyError)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled);
- // See OnNotifyError for why |this| mustn't be used after OnNotifyError might
- // have been called above.
- return handled;
-}
-
-void GpuVideoEncodeAcceleratorHost::OnChannelError() {
- DCHECK(CalledOnValidThread());
- if (channel_) {
- if (encoder_route_id_ != MSG_ROUTING_NONE)
- channel_->RemoveRoute(encoder_route_id_);
- channel_ = NULL;
- }
- PostNotifyError(FROM_HERE, kPlatformFailureError, "OnChannelError()");
-}
-
-media::VideoEncodeAccelerator::SupportedProfiles
-GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return media::VideoEncodeAccelerator::SupportedProfiles();
- return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
- channel_->gpu_info().video_encode_accelerator_supported_profiles);
-}
-
-bool GpuVideoEncodeAcceleratorHost::Initialize(
- media::VideoPixelFormat input_format,
- const gfx::Size& input_visible_size,
- media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- Client* client) {
- DCHECK(CalledOnValidThread());
- client_ = client;
- if (!impl_) {
- DLOG(ERROR) << "impl_ destroyed";
- return false;
- }
-
- int32_t route_id = channel_->GenerateRouteID();
- channel_->AddRoute(route_id, weak_this_factory_.GetWeakPtr());
-
- bool succeeded = false;
- Send(new GpuCommandBufferMsg_CreateVideoEncoder(
- impl_->route_id(), input_format, input_visible_size, output_profile,
- initial_bitrate, route_id, &succeeded));
- if (!succeeded) {
- DLOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoEncoder()) failed";
- channel_->RemoveRoute(route_id);
- return false;
- }
- encoder_route_id_ = route_id;
- return true;
-}
-
-void GpuVideoEncodeAcceleratorHost::Encode(
- const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe) {
- DCHECK(CalledOnValidThread());
- DCHECK_EQ(media::PIXEL_FORMAT_I420, frame->format());
- if (!channel_)
- return;
-
- switch (frame->storage_type()) {
- case media::VideoFrame::STORAGE_SHMEM:
- EncodeSharedMemoryFrame(frame, force_keyframe);
- break;
- case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS:
- EncodeGpuMemoryBufferFrame(frame, force_keyframe);
- break;
- default:
- PostNotifyError(FROM_HERE, kPlatformFailureError,
- "Encode(): cannot encode frame with invalid handles");
- return;
- }
-
- frame_map_[next_frame_id_] = frame;
-
- // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
- next_frame_id_ = (next_frame_id_ + 1) & 0x3FFFFFFF;
-}
-
-void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer(
- const media::BitstreamBuffer& buffer) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
-
- base::SharedMemoryHandle handle =
- channel_->ShareToGpuProcess(buffer.handle());
- if (!base::SharedMemory::IsHandleValid(handle)) {
- PostNotifyError(
- FROM_HERE, kPlatformFailureError,
- base::StringPrintf("UseOutputBitstreamBuffer(): failed to duplicate "
- "buffer handle for GPU process: buffer.id()=%d",
- buffer.id()));
- return;
- }
- Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer(
- encoder_route_id_, buffer.id(), handle, buffer.size()));
-}
-
-void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange(
- uint32_t bitrate,
- uint32_t framerate) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return;
-
- Send(new AcceleratedVideoEncoderMsg_RequestEncodingParametersChange(
- encoder_route_id_, bitrate, framerate));
-}
-
-void GpuVideoEncodeAcceleratorHost::Destroy() {
- DCHECK(CalledOnValidThread());
- if (channel_)
- Send(new AcceleratedVideoEncoderMsg_Destroy(encoder_route_id_));
- client_ = NULL;
- delete this;
-}
-
-void GpuVideoEncodeAcceleratorHost::OnWillDeleteImpl() {
- DCHECK(CalledOnValidThread());
- impl_ = NULL;
-
- // The CommandBufferProxyImpl is going away; error out this VEA.
- OnChannelError();
-}
-
-void GpuVideoEncodeAcceleratorHost::EncodeGpuMemoryBufferFrame(
- const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe){
- DCHECK_EQ(media::VideoFrame::NumPlanes(media::PIXEL_FORMAT_I420),
- frame->gpu_memory_buffer_handles().size());
- AcceleratedVideoEncoderMsg_Encode_Params2 params;
- params.frame_id = next_frame_id_;
- params.timestamp = frame->timestamp();
- bool requires_sync_point = false;
- for (const auto& handle : frame->gpu_memory_buffer_handles()) {
- gfx::GpuMemoryBufferHandle new_handle =
- channel_->ShareGpuMemoryBufferToGpuProcess(handle,
- &requires_sync_point);
- if (new_handle.is_null()) {
- PostNotifyError(FROM_HERE, kPlatformFailureError,
- "EncodeGpuMemoryBufferFrame(): failed to share gpu "
- "memory buffer handle for gpu process");
- return;
- }
- params.gpu_memory_buffer_handles.push_back(new_handle);
- }
- params.size = frame->coded_size();
- params.force_keyframe = force_keyframe;
-
- Send(new AcceleratedVideoEncoderMsg_Encode2(encoder_route_id_, params));
-}
-
-void GpuVideoEncodeAcceleratorHost::EncodeSharedMemoryFrame(
- const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe){
- if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) {
- PostNotifyError(FROM_HERE, kPlatformFailureError,
- "EncodeSharedMemory(): cannot encode frame with invalid "
- "shared memory handle");
- return;
- }
-
- AcceleratedVideoEncoderMsg_Encode_Params params;
- params.frame_id = next_frame_id_;
- params.timestamp = frame->timestamp();
- params.buffer_handle =
- channel_->ShareToGpuProcess(frame->shared_memory_handle());
- if (!base::SharedMemory::IsHandleValid(params.buffer_handle)) {
- PostNotifyError(FROM_HERE, kPlatformFailureError,
- "Encode(): failed to duplicate shared memory buffer handle "
- "for GPU process");
- return;
- }
- params.buffer_offset =
- base::checked_cast<uint32_t>(frame->shared_memory_offset());
- params.buffer_size =
- media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
- params.force_keyframe = force_keyframe;
-
- Send(new AcceleratedVideoEncoderMsg_Encode(encoder_route_id_, params));
-}
-
-void GpuVideoEncodeAcceleratorHost::PostNotifyError(
- const tracked_objects::Location& location, Error error,
- const std::string& message) {
- DCHECK(CalledOnValidThread());
- DLOG(ERROR) << "Error from " << location.function_name()
- << "(" << location.file_name() << ":"
- << location.line_number() << ") "
- << message << " (error = " << error << ")";
- // Post the error notification back to this thread, to avoid re-entrancy.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&GpuVideoEncodeAcceleratorHost::OnNotifyError,
- weak_this_factory_.GetWeakPtr(), error));
-}
-
-void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) {
- DCHECK(CalledOnValidThread());
- uint32_t message_type = message->type();
- if (!channel_->Send(message)) {
- PostNotifyError(FROM_HERE, kPlatformFailureError,
- base::StringPrintf("Send(%d) failed", message_type));
- }
-}
-
-void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers(
- uint32_t input_count,
- const gfx::Size& input_coded_size,
- uint32_t output_buffer_size) {
- DCHECK(CalledOnValidThread());
- DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count
- << ", input_coded_size=" << input_coded_size.ToString()
- << ", output_buffer_size=" << output_buffer_size;
- if (client_) {
- client_->RequireBitstreamBuffers(
- input_count, input_coded_size, output_buffer_size);
- }
-}
-
-void GpuVideoEncodeAcceleratorHost::OnNotifyInputDone(int32_t frame_id) {
- DCHECK(CalledOnValidThread());
- DVLOG(3) << "OnNotifyInputDone(): frame_id=" << frame_id;
- // Fun-fact: std::hash_map is not spec'd to be re-entrant; since freeing a
- // frame can trigger a further encode to be kicked off and thus an .insert()
- // back into the map, we separate the frame's dtor running from the .erase()
- // running by holding on to the frame temporarily. This isn't "just
- // theoretical" - Android's std::hash_map crashes if we don't do this.
- scoped_refptr<media::VideoFrame> frame = frame_map_[frame_id];
- if (!frame_map_.erase(frame_id)) {
- DLOG(ERROR) << "OnNotifyInputDone(): "
- "invalid frame_id=" << frame_id;
- // See OnNotifyError for why this needs to be the last thing in this
- // function.
- OnNotifyError(kPlatformFailureError);
- return;
- }
- frame = NULL; // Not necessary but nice to be explicit; see fun-fact above.
-}
-
-void GpuVideoEncodeAcceleratorHost::OnBitstreamBufferReady(
- int32_t bitstream_buffer_id,
- uint32_t payload_size,
- bool key_frame) {
- DCHECK(CalledOnValidThread());
- DVLOG(3) << "OnBitstreamBufferReady(): "
- "bitstream_buffer_id=" << bitstream_buffer_id
- << ", payload_size=" << payload_size
- << ", key_frame=" << key_frame;
- if (client_)
- client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame);
-}
-
-void GpuVideoEncodeAcceleratorHost::OnNotifyError(Error error) {
- DCHECK(CalledOnValidThread());
- DVLOG(2) << "OnNotifyError(): error=" << error;
- if (!client_)
- return;
- weak_this_factory_.InvalidateWeakPtrs();
-
- // Client::NotifyError() may Destroy() |this|, so calling it needs to be the
- // last thing done on this stack!
- media::VideoEncodeAccelerator::Client* client = NULL;
- std::swap(client_, client);
- client->NotifyError(error);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h b/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h
deleted file mode 100644
index 38995938259..00000000000
--- a/chromium/content/common/gpu/client/gpu_video_encode_accelerator_host.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2013 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 CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
-#define CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "content/common/gpu/client/command_buffer_proxy_impl.h"
-#include "gpu/config/gpu_info.h"
-#include "ipc/ipc_listener.h"
-#include "media/video/video_encode_accelerator.h"
-
-namespace gfx {
-struct GpuMemoryBufferHandle;
-class Size;
-} // namespace gfx
-
-namespace media {
-class VideoFrame;
-} // namespace media
-
-namespace tracked_objects {
-class Location;
-} // namespace tracked_objects
-
-namespace content {
-class GpuChannelHost;
-
-// This class is the renderer-side host for the VideoEncodeAccelerator in the
-// GPU process, coordinated over IPC.
-class GpuVideoEncodeAcceleratorHost
- : public IPC::Listener,
- public media::VideoEncodeAccelerator,
- public CommandBufferProxyImpl::DeletionObserver,
- public base::NonThreadSafe {
- public:
- // |this| is guaranteed not to outlive |channel| and |impl|. (See comments
- // for |channel_| and |impl_|.)
- GpuVideoEncodeAcceleratorHost(GpuChannelHost* channel,
- CommandBufferProxyImpl* impl);
-
- // IPC::Listener implementation.
- bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelError() override;
-
- // media::VideoEncodeAccelerator implementation.
- SupportedProfiles GetSupportedProfiles() override;
- bool Initialize(media::VideoPixelFormat input_format,
- const gfx::Size& input_visible_size,
- media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- Client* client) override;
- void Encode(const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe) override;
- void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) override;
- void RequestEncodingParametersChange(uint32_t bitrate,
- uint32_t framerate_num) override;
- void Destroy() override;
-
- // CommandBufferProxyImpl::DeletionObserver implementation.
- void OnWillDeleteImpl() override;
-
- private:
- // Only Destroy() should be deleting |this|.
- ~GpuVideoEncodeAcceleratorHost() override;
-
- // Encode specific video frame types.
- void EncodeGpuMemoryBufferFrame(const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe);
- void EncodeSharedMemoryFrame(const scoped_refptr<media::VideoFrame>& frame,
- bool force_keyframe);
-
- // Notify |client_| of an error. Posts a task to avoid re-entrancy.
- void PostNotifyError(const tracked_objects::Location& location,
- Error error, const std::string& message);
-
- void Send(IPC::Message* message);
-
- // IPC handlers, proxying media::VideoEncodeAccelerator::Client for the GPU
- // process. Should not be called directly.
- void OnRequireBitstreamBuffers(uint32_t input_count,
- const gfx::Size& input_coded_size,
- uint32_t output_buffer_size);
- void OnNotifyInputDone(int32_t frame_id);
- void OnBitstreamBufferReady(int32_t bitstream_buffer_id,
- uint32_t payload_size,
- bool key_frame);
- void OnNotifyError(Error error);
-
- // Unowned reference to the GpuChannelHost to send IPC messages to the GPU
- // process. |channel_| outlives |impl_|, so the reference is always valid as
- // long as it is not NULL.
- GpuChannelHost* channel_;
-
- // Route ID for the associated encoder in the GPU process.
- int32_t encoder_route_id_;
-
- // The client that will receive callbacks from the encoder.
- Client* client_;
-
- // Unowned reference to the CommandBufferProxyImpl that created us. |this|
- // registers as a DeletionObserver of |impl_|, so the reference is always
- // valid as long as it is not NULL.
- CommandBufferProxyImpl* impl_;
-
- // media::VideoFrames sent to the encoder.
- // base::IDMap not used here, since that takes pointers, not scoped_refptr.
- typedef base::hash_map<int32_t, scoped_refptr<media::VideoFrame>> FrameMap;
- FrameMap frame_map_;
-
- // ID serial number for the next frame to send to the GPU process.
- int32_t next_frame_id_;
-
- // WeakPtr factory for posting tasks back to itself.
- base::WeakPtrFactory<GpuVideoEncodeAcceleratorHost> weak_this_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuVideoEncodeAcceleratorHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
diff --git a/chromium/content/common/gpu/client/grcontext_for_gles2_interface.cc b/chromium/content/common/gpu/client/grcontext_for_gles2_interface.cc
new file mode 100644
index 00000000000..cebdfd7745c
--- /dev/null
+++ b/chromium/content/common/gpu/client/grcontext_for_gles2_interface.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2013 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 "content/common/gpu/client/grcontext_for_gles2_interface.h"
+
+#include <stddef.h>
+#include <string.h>
+#include <utility>
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/trace_event/trace_event.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
+#include "third_party/skia/include/gpu/GrContext.h"
+#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
+
+namespace content {
+
+GrContextForGLES2Interface::GrContextForGLES2Interface(
+ gpu::gles2::GLES2Interface* gl) {
+ sk_sp<GrGLInterface> interface(
+ skia_bindings::CreateGLES2InterfaceBindings(gl));
+ gr_context_ =
+ sk_sp<GrContext>(GrContext::Create(kOpenGL_GrBackend,
+ // GrContext takes ownership of |interface|.
+ reinterpret_cast<GrBackendContext>(interface.get())));
+ if (gr_context_) {
+ // The limit of the number of GPU resources we hold in the GrContext's
+ // GPU cache.
+ static const int kMaxGaneshResourceCacheCount = 2048;
+ // The limit of the bytes allocated toward GPU resources in the GrContext's
+ // GPU cache.
+ static const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024;
+
+ gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount,
+ kMaxGaneshResourceCacheBytes);
+ }
+}
+
+GrContextForGLES2Interface::~GrContextForGLES2Interface() {
+ // At this point the GLES2Interface is going to be destroyed, so have
+ // the GrContext clean up and not try to use it anymore.
+ if (gr_context_)
+ gr_context_->releaseResourcesAndAbandonContext();
+}
+
+void GrContextForGLES2Interface::OnLostContext() {
+ if (gr_context_)
+ gr_context_->abandonContext();
+}
+
+void GrContextForGLES2Interface::FreeGpuResources() {
+ if (gr_context_) {
+ TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources",
+ TRACE_EVENT_SCOPE_THREAD);
+ gr_context_->freeGpuResources();
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/client/grcontext_for_gles2_interface.h b/chromium/content/common/gpu/client/grcontext_for_gles2_interface.h
new file mode 100644
index 00000000000..354092a9592
--- /dev/null
+++ b/chromium/content/common/gpu/client/grcontext_for_gles2_interface.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 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 CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_GLES2_INTERFACE_H_
+#define CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_GLES2_INTERFACE_H_
+
+#include "base/macros.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
+
+class GrContext;
+
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
+namespace content {
+
+// This class binds an offscreen GrContext to an offscreen context3d. The
+// context3d is used by the GrContext so must be valid as long as this class
+// is alive.
+class GrContextForGLES2Interface {
+ public:
+ explicit GrContextForGLES2Interface(gpu::gles2::GLES2Interface* gl);
+ virtual ~GrContextForGLES2Interface();
+
+ GrContext* get() { return gr_context_.get(); }
+
+ void OnLostContext();
+ void FreeGpuResources();
+
+ private:
+ sk_sp<class GrContext> gr_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(GrContextForGLES2Interface);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_GLES2_INTERFACE_H_
diff --git a/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.cc b/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.cc
deleted file mode 100644
index 5cd4944db68..00000000000
--- a/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2013 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 "content/common/gpu/client/grcontext_for_webgraphicscontext3d.h"
-
-#include <stddef.h>
-#include <string.h>
-#include <utility>
-
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "base/trace_event/trace_event.h"
-#include "gpu/blink/webgraphicscontext3d_impl.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-
-using gpu_blink::WebGraphicsContext3DImpl;
-
-namespace content {
-
-namespace {
-
-// Singleton used to initialize and terminate the gles2 library.
-class GLES2Initializer {
- public:
- GLES2Initializer() { gles2::Initialize(); }
-
- ~GLES2Initializer() { gles2::Terminate(); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
-};
-
-base::LazyInstance<GLES2Initializer> g_gles2_initializer =
- LAZY_INSTANCE_INITIALIZER;
-
-void BindWebGraphicsContext3DGLContextCallback(const GrGLInterface* interface) {
- gles2::SetGLContext(static_cast<const GrGLInterfaceForWebGraphicsContext3D*>(
- interface)->WebContext3D()->GetGLInterface());
-}
-
-} // namespace anonymous
-
-GrContextForWebGraphicsContext3D::GrContextForWebGraphicsContext3D(
- skia::RefPtr<GrGLInterfaceForWebGraphicsContext3D> gr_interface) {
- if (!gr_interface || !gr_interface->WebContext3D())
- return;
-
- // Ensure the gles2 library is initialized first in a thread safe way.
- g_gles2_initializer.Get();
- gles2::SetGLContext(gr_interface->WebContext3D()->GetGLInterface());
-
- skia_bindings::InitCommandBufferSkiaGLBinding(gr_interface.get());
-
- gr_interface->fCallback = BindWebGraphicsContext3DGLContextCallback;
-
- gr_context_ = skia::AdoptRef(GrContext::Create(
- kOpenGL_GrBackend,
- reinterpret_cast<GrBackendContext>(gr_interface.get())));
- if (gr_context_) {
- // The limit of the number of GPU resources we hold in the GrContext's
- // GPU cache.
- static const int kMaxGaneshResourceCacheCount = 2048;
- // The limit of the bytes allocated toward GPU resources in the GrContext's
- // GPU cache.
- static const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024;
-
- gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount,
- kMaxGaneshResourceCacheBytes);
- }
-}
-
-GrContextForWebGraphicsContext3D::~GrContextForWebGraphicsContext3D() {
-}
-
-void GrContextForWebGraphicsContext3D::OnLostContext() {
- if (gr_context_)
- gr_context_->abandonContext();
-}
-
-void GrContextForWebGraphicsContext3D::FreeGpuResources() {
- if (gr_context_) {
- TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources", \
- TRACE_EVENT_SCOPE_THREAD);
- gr_context_->freeGpuResources();
- }
-}
-
-GrGLInterfaceForWebGraphicsContext3D::GrGLInterfaceForWebGraphicsContext3D(
- scoped_ptr<gpu_blink::WebGraphicsContext3DImpl> context3d)
- : context3d_(std::move(context3d)) {}
-
-void GrGLInterfaceForWebGraphicsContext3D::BindToCurrentThread() {
- context_thread_checker_.DetachFromThread();
-}
-
-GrGLInterfaceForWebGraphicsContext3D::~GrGLInterfaceForWebGraphicsContext3D() {
- DCHECK(context_thread_checker_.CalledOnValidThread());
-#if !defined(NDEBUG)
- // Set all the function pointers to zero, in order to crash if function
- // pointers are used after free.
- memset(&fFunctions, 0, sizeof(GrGLInterface::Functions));
-#endif
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.h b/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.h
deleted file mode 100644
index 7597f906a58..00000000000
--- a/chromium/content/common/gpu/client/grcontext_for_webgraphicscontext3d.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2013 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 CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_WEBGRAPHICSCONTEXT3D_H_
-#define CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_WEBGRAPHICSCONTEXT3D_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
-
-class GrContext;
-
-namespace gpu_blink {
-class WebGraphicsContext3DImpl;
-}
-
-namespace content {
-
-// Wrap WebGraphicsContext3DImpl into a GrGLInterface object, which allows
-// the WebGraphicsContext3DImpl to be jointly refcounted (indirectly)
-// by the GrContext and the context provider. This makes it legal for the
-// GrContext to be invoked when it outlives the context provider that created
-// it. By doing this we no longer have to worry about use after free errors
-// caused a lack of consideration for object destruction order.
-class GrGLInterfaceForWebGraphicsContext3D final : public GrGLInterface {
- public:
- GrGLInterfaceForWebGraphicsContext3D(
- scoped_ptr<gpu_blink::WebGraphicsContext3DImpl> context3d);
- ~GrGLInterfaceForWebGraphicsContext3D() final;
-
- void BindToCurrentThread();
-
- gpu_blink::WebGraphicsContext3DImpl* WebContext3D() const {
- return context3d_.get();
- }
- private:
- base::ThreadChecker context_thread_checker_;
- scoped_ptr<gpu_blink::WebGraphicsContext3DImpl> context3d_;
-};
-
-// This class binds an offscreen GrContext to an offscreen context3d. The
-// context3d is used by the GrContext so must be valid as long as this class
-// is alive.
-class GrContextForWebGraphicsContext3D {
- public:
- explicit GrContextForWebGraphicsContext3D(
- skia::RefPtr<GrGLInterfaceForWebGraphicsContext3D> context3d);
- virtual ~GrContextForWebGraphicsContext3D();
-
- GrContext* get() { return gr_context_.get(); }
-
- void OnLostContext();
- void FreeGpuResources();
-
- private:
- skia::RefPtr<class GrContext> gr_context_;
-
- DISALLOW_COPY_AND_ASSIGN(GrContextForWebGraphicsContext3D);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_CLIENT_GRCONTEXT_FOR_WEBGRAPHICSCONTEXT3D_H_
diff --git a/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index f7783397057..708a3da8ee0 100644
--- a/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -23,22 +23,19 @@
#include "base/metrics/histogram.h"
#include "base/profiler/scoped_tracker.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/public/common/content_constants.h"
-#include "content/public/common/content_switches.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_trace_implementation.h"
+#include "gpu/command_buffer/client/gpu_switches.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
#include "third_party/skia/include/core/SkTypes.h"
-using blink::WGC3Denum;
-
namespace content {
namespace {
@@ -46,14 +43,15 @@ namespace {
static base::LazyInstance<base::Lock>::Leaky
g_default_share_groups_lock = LAZY_INSTANCE_INITIALIZER;
-typedef std::map<GpuChannelHost*,
- scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> >
+typedef std::map<
+ gpu::GpuChannelHost*,
+ scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>>
ShareGroupMap;
static base::LazyInstance<ShareGroupMap> g_default_share_groups =
LAZY_INSTANCE_INITIALIZER;
scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>
- GetDefaultShareGroupForHost(GpuChannelHost* host) {
+GetDefaultShareGroupForHost(gpu::GpuChannelHost* host) {
base::AutoLock lock(g_default_share_groups_lock.Get());
ShareGroupMap& share_groups = g_default_share_groups.Get();
@@ -84,34 +82,38 @@ WebGraphicsContext3DCommandBufferImpl::ShareGroup::~ShareGroup() {
}
WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
- int surface_id,
+ gpu::SurfaceHandle surface_handle,
const GURL& active_url,
- GpuChannelHost* host,
- const Attributes& attributes,
- bool lose_context_when_out_of_memory,
+ gpu::GpuChannelHost* host,
+ const gpu::gles2::ContextCreationAttribHelper& attributes,
+ gfx::GpuPreference gpu_preference,
+ bool share_resources,
+ bool automatic_flushes,
const SharedMemoryLimits& limits,
WebGraphicsContext3DCommandBufferImpl* share_context)
- : lose_context_when_out_of_memory_(lose_context_when_out_of_memory),
+ : automatic_flushes_(automatic_flushes),
attributes_(attributes),
- visible_(false),
host_(host),
- surface_id_(surface_id),
+ surface_handle_(surface_handle),
active_url_(active_url),
- context_type_(CONTEXT_TYPE_UNKNOWN),
- gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu
- : gfx::PreferIntegratedGpu),
+ gpu_preference_(gpu_preference),
mem_limits_(limits),
weak_ptr_factory_(this) {
- if (attributes_.webGL)
- context_type_ = OFFSCREEN_CONTEXT_FOR_WEBGL;
+ switch (attributes.context_type) {
+ case gpu::gles2::CONTEXT_TYPE_OPENGLES2:
+ case gpu::gles2::CONTEXT_TYPE_OPENGLES3:
+ context_type_ = CONTEXT_TYPE_UNKNOWN;
+ case gpu::gles2::CONTEXT_TYPE_WEBGL1:
+ case gpu::gles2::CONTEXT_TYPE_WEBGL2:
+ context_type_ = OFFSCREEN_CONTEXT_FOR_WEBGL;
+ }
if (share_context) {
- DCHECK(!attributes_.shareResources);
+ DCHECK(!share_resources);
share_group_ = share_context->share_group_;
+ } else if (share_resources) {
+ share_group_ = GetDefaultShareGroupForHost(host);
} else {
- share_group_ = attributes_.shareResources
- ? GetDefaultShareGroupForHost(host)
- : scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>(
- new ShareGroup());
+ share_group_ = make_scoped_refptr(new ShareGroup);
}
}
@@ -138,7 +140,7 @@ bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"125248 WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL"));
- if (!CreateContext(surface_id_ != 0)) {
+ if (!CreateContext()) {
Destroy();
initialize_failed_ = true;
@@ -157,44 +159,31 @@ bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D",
"CommandBufferContext");
- visible_ = true;
initialized_ = true;
return true;
}
bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
- bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) {
+ WebGraphicsContext3DCommandBufferImpl* share_context) {
if (!host_.get())
return false;
- CommandBufferProxyImpl* share_group_command_buffer = NULL;
+ gpu::CommandBufferProxyImpl* share_group_command_buffer = NULL;
if (share_context) {
share_group_command_buffer = share_context->GetCommandBufferProxy();
}
- ::gpu::gles2::ContextCreationAttribHelper attribs_for_gles2;
- ConvertAttributes(attributes_, &attribs_for_gles2);
- attribs_for_gles2.lose_context_when_out_of_memory =
- lose_context_when_out_of_memory_;
- DCHECK(attribs_for_gles2.buffer_preserved);
- std::vector<int32_t> attribs;
- attribs_for_gles2.Serialize(&attribs);
+ DCHECK(attributes_.buffer_preserved);
+ std::vector<int32_t> serialized_attributes;
+ attributes_.Serialize(&serialized_attributes);
// Create a proxy to a command buffer in the GPU process.
- if (onscreen) {
- command_buffer_ =
- host_->CreateViewCommandBuffer(surface_id_, share_group_command_buffer,
- GpuChannelHost::kDefaultStreamId,
- GpuChannelHost::kDefaultStreamPriority,
- attribs, active_url_, gpu_preference_);
- } else {
- command_buffer_ = host_->CreateOffscreenCommandBuffer(
- gfx::Size(1, 1), share_group_command_buffer,
- GpuChannelHost::kDefaultStreamId,
- GpuChannelHost::kDefaultStreamPriority, attribs, active_url_,
- gpu_preference_);
- }
+ command_buffer_ = host_->CreateCommandBuffer(
+ surface_handle_, gfx::Size(), share_group_command_buffer,
+ gpu::GpuChannelHost::kDefaultStreamId,
+ gpu::GpuChannelHost::kDefaultStreamPriority, serialized_attributes,
+ active_url_, gpu_preference_);
if (!command_buffer_) {
DLOG(ERROR) << "GpuChannelHost failed to create command buffer.";
@@ -213,7 +202,7 @@ bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
return result;
}
-bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
+bool WebGraphicsContext3DCommandBufferImpl::CreateContext() {
TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::CreateContext");
scoped_refptr<gpu::gles2::ShareGroup> gles2_share_group;
@@ -225,7 +214,7 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
share_group_lock.reset(new base::AutoLock(share_group_->lock()));
share_context = share_group_->GetAnyContextLocked();
- if (!InitializeCommandBuffer(onscreen, share_context)) {
+ if (!InitializeCommandBuffer(share_context)) {
LOG(ERROR) << "Failed to initialize command buffer.";
return false;
}
@@ -243,7 +232,7 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
return false;
}
- if (attributes_.noAutomaticFlushes)
+ if (!automatic_flushes_)
gles2_helper_->SetAutomaticFlushes(false);
// Create a transfer buffer used to copy resources between the renderer
// process and the GPU process.
@@ -251,15 +240,17 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
DCHECK(host_.get());
- // Create the object exposing the OpenGL API.
- const bool bind_generates_resources = false;
+ const bool bind_generates_resource = attributes_.bind_generates_resource;
+ const bool lose_context_when_out_of_memory =
+ attributes_.lose_context_when_out_of_memory;
const bool support_client_side_arrays = false;
+ // Create the object exposing the OpenGL API.
real_gl_.reset(new gpu::gles2::GLES2Implementation(
gles2_helper_.get(), gles2_share_group.get(), transfer_buffer_.get(),
- bind_generates_resources, lose_context_when_out_of_memory_,
+ bind_generates_resource, lose_context_when_out_of_memory,
support_client_side_arrays, command_buffer_.get()));
- setGLInterface(real_gl_.get());
+ SetGLInterface(real_gl_.get());
if (!real_gl_->Initialize(
mem_limits_.start_transfer_buffer_size,
@@ -276,7 +267,7 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableGpuClientTracing)) {
trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(GetGLInterface()));
- setGLInterface(trace_gl_.get());
+ SetGLInterface(trace_gl_.get());
}
return true;
}
@@ -306,7 +297,7 @@ void WebGraphicsContext3DCommandBufferImpl::Destroy() {
// issued on this context might not be visible to other contexts in the
// share group.
gl->Flush();
- setGLInterface(NULL);
+ SetGLInterface(nullptr);
}
trace_gl_.reset();
@@ -316,7 +307,7 @@ void WebGraphicsContext3DCommandBufferImpl::Destroy() {
real_gl_.reset();
command_buffer_.reset();
- host_ = NULL;
+ host_ = nullptr;
}
gpu::ContextSupport*
@@ -336,9 +327,11 @@ bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
// static
WebGraphicsContext3DCommandBufferImpl*
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- GpuChannelHost* host,
- const WebGraphicsContext3D::Attributes& attributes,
- bool lose_context_when_out_of_memory,
+ gpu::GpuChannelHost* host,
+ const gpu::gles2::ContextCreationAttribHelper& attributes,
+ gfx::GpuPreference gpu_preference,
+ bool share_resources,
+ bool automatic_flushes,
const GURL& active_url,
const SharedMemoryLimits& limits,
WebGraphicsContext3DCommandBufferImpl* share_context) {
@@ -349,13 +342,8 @@ WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
return NULL;
return new WebGraphicsContext3DCommandBufferImpl(
- 0,
- active_url,
- host,
- attributes,
- lose_context_when_out_of_memory,
- limits,
- share_context);
+ gpu::kNullSurfaceHandle, active_url, host, attributes, gpu_preference,
+ share_resources, automatic_flushes, limits, share_context);
}
void WebGraphicsContext3DCommandBufferImpl::OnContextLost() {
diff --git a/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
index b556c1bcdf5..1bbd7202eb6 100644
--- a/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
+++ b/chromium/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
@@ -18,17 +18,19 @@
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "content/common/gpu/client/command_buffer_metrics.h"
-#include "content/common/gpu/client/command_buffer_proxy_impl.h"
#include "gpu/blink/webgraphicscontext3d_impl.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/ipc/client/command_buffer_proxy_impl.h"
+#include "gpu/ipc/common/surface_handle.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebString.h"
-#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gpu_preference.h"
#include "url/gurl.h"
namespace gpu {
class ContextSupport;
+class GpuChannelHost;
class TransferBuffer;
namespace gles2 {
@@ -39,7 +41,6 @@ class GLES2Interface;
}
namespace content {
-class GpuChannelHost;
const size_t kDefaultCommandBufferSize = 1024 * 1024;
const size_t kDefaultStartTransferBufferSize = 1 * 1024 * 1024;
@@ -108,17 +109,19 @@ class WebGraphicsContext3DCommandBufferImpl
};
WebGraphicsContext3DCommandBufferImpl(
- int surface_id,
+ gpu::SurfaceHandle surface_handle,
const GURL& active_url,
- GpuChannelHost* host,
- const Attributes& attributes,
- bool lose_context_when_out_of_memory,
+ gpu::GpuChannelHost* host,
+ const gpu::gles2::ContextCreationAttribHelper& attributes,
+ gfx::GpuPreference gpu_preference,
+ bool share_resources,
+ bool automatic_flushes,
const SharedMemoryLimits& limits,
WebGraphicsContext3DCommandBufferImpl* share_context);
~WebGraphicsContext3DCommandBufferImpl() override;
- CommandBufferProxyImpl* GetCommandBufferProxy() {
+ gpu::CommandBufferProxyImpl* GetCommandBufferProxy() {
return command_buffer_.get();
}
@@ -135,13 +138,15 @@ class WebGraphicsContext3DCommandBufferImpl
// Create & initialize a WebGraphicsContext3DCommandBufferImpl. Return NULL
// on any failure.
static CONTENT_EXPORT WebGraphicsContext3DCommandBufferImpl*
- CreateOffscreenContext(
- GpuChannelHost* host,
- const WebGraphicsContext3D::Attributes& attributes,
- bool lose_context_when_out_of_memory,
- const GURL& active_url,
- const SharedMemoryLimits& limits,
- WebGraphicsContext3DCommandBufferImpl* share_context);
+ CreateOffscreenContext(
+ gpu::GpuChannelHost* host,
+ const gpu::gles2::ContextCreationAttribHelper& attributes,
+ gfx::GpuPreference gpu_preference,
+ bool share_resources,
+ bool automatic_flushes,
+ const GURL& active_url,
+ const SharedMemoryLimits& limits,
+ WebGraphicsContext3DCommandBufferImpl* share_context);
size_t GetMappedMemoryLimit() {
return mem_limits_.mapped_memory_reclaim_limit;
@@ -166,7 +171,7 @@ class WebGraphicsContext3DCommandBufferImpl
// thread).
bool MaybeInitializeGL();
- bool InitializeCommandBuffer(bool onscreen,
+ bool InitializeCommandBuffer(
WebGraphicsContext3DCommandBufferImpl* share_context);
void Destroy();
@@ -178,30 +183,28 @@ class WebGraphicsContext3DCommandBufferImpl
//
// NOTE: on Mac OS X, this entry point is only used to set up the
// accelerated compositor's output. On this platform, we actually pass
- // a gfx::PluginWindowHandle in place of the gfx::NativeViewId,
+ // a gpu::SurfaceHandle in place of the gfx::NativeViewId,
// because the facility to allocate a fake PluginWindowHandle is
// already in place. We could add more entry points and messages to
// allocate both fake PluginWindowHandles and NativeViewIds and map
// from fake NativeViewIds to PluginWindowHandles, but this seems like
// unnecessary complexity at the moment.
- bool CreateContext(bool onscreen);
+ bool CreateContext();
virtual void OnContextLost();
- bool lose_context_when_out_of_memory_;
- blink::WebGraphicsContext3D::Attributes attributes_;
-
- bool visible_;
+ bool automatic_flushes_;
+ gpu::gles2::ContextCreationAttribHelper attributes_;
// State needed by MaybeInitializeGL.
- scoped_refptr<GpuChannelHost> host_;
- int32_t surface_id_;
+ scoped_refptr<gpu::GpuChannelHost> host_;
+ gpu::SurfaceHandle surface_handle_;
GURL active_url_;
CommandBufferContextType context_type_;
gfx::GpuPreference gpu_preference_;
- scoped_ptr<CommandBufferProxyImpl> command_buffer_;
+ scoped_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
scoped_ptr<gpu::gles2::GLES2Implementation> real_gl_;
diff --git a/chromium/content/common/gpu/gpu_channel.cc b/chromium/content/common/gpu/gpu_channel.cc
deleted file mode 100644
index e3f920d96b0..00000000000
--- a/chromium/content/common/gpu/gpu_channel.cc
+++ /dev/null
@@ -1,1086 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_channel.h"
-
-#include <utility>
-
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-
-#include <algorithm>
-#include <deque>
-#include <set>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "base/synchronization/lock.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/timer/timer.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/media/gpu_jpeg_decode_accelerator.h"
-#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/value_state.h"
-#include "gpu/command_buffer/service/gpu_scheduler.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "gpu/command_buffer/service/valuebuffer_manager.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/message_filter.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_image_shared_memory.h"
-#include "ui/gl/gl_surface.h"
-
-#if defined(OS_POSIX)
-#include "ipc/ipc_channel_posix.h"
-#endif
-
-namespace content {
-namespace {
-
-// Number of milliseconds between successive vsync. Many GL commands block
-// on vsync, so thresholds for preemption should be multiples of this.
-const int64_t kVsyncIntervalMs = 17;
-
-// Amount of time that we will wait for an IPC to be processed before
-// preempting. After a preemption, we must wait this long before triggering
-// another preemption.
-const int64_t kPreemptWaitTimeMs = 2 * kVsyncIntervalMs;
-
-// Once we trigger a preemption, the maximum duration that we will wait
-// before clearing the preemption.
-const int64_t kMaxPreemptTimeMs = kVsyncIntervalMs;
-
-// Stop the preemption once the time for the longest pending IPC drops
-// below this threshold.
-const int64_t kStopPreemptThresholdMs = kVsyncIntervalMs;
-
-} // anonymous namespace
-
-scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create(
- const base::WeakPtr<GpuChannel>& gpu_channel,
- base::SingleThreadTaskRunner* task_runner,
- gpu::SyncPointManager* sync_point_manager) {
- return new GpuChannelMessageQueue(gpu_channel, task_runner,
- sync_point_manager);
-}
-
-scoped_refptr<gpu::SyncPointOrderData>
-GpuChannelMessageQueue::GetSyncPointOrderData() {
- return sync_point_order_data_;
-}
-
-GpuChannelMessageQueue::GpuChannelMessageQueue(
- const base::WeakPtr<GpuChannel>& gpu_channel,
- base::SingleThreadTaskRunner* task_runner,
- gpu::SyncPointManager* sync_point_manager)
- : enabled_(true),
- sync_point_order_data_(gpu::SyncPointOrderData::Create()),
- gpu_channel_(gpu_channel),
- task_runner_(task_runner),
- sync_point_manager_(sync_point_manager) {}
-
-GpuChannelMessageQueue::~GpuChannelMessageQueue() {
- DCHECK(channel_messages_.empty());
-}
-
-uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const {
- return sync_point_order_data_->unprocessed_order_num();
-}
-
-uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const {
- return sync_point_order_data_->processed_order_num();
-}
-
-void GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) {
- base::AutoLock auto_lock(channel_messages_lock_);
- if (enabled_)
- PushMessageHelper(make_scoped_ptr(new GpuChannelMessage(message)));
-}
-
-bool GpuChannelMessageQueue::GenerateSyncPointMessage(
- const IPC::Message& message,
- bool retire_sync_point,
- uint32_t* sync_point) {
- DCHECK_EQ((uint32_t)GpuCommandBufferMsg_InsertSyncPoint::ID, message.type());
- DCHECK(sync_point);
- base::AutoLock auto_lock(channel_messages_lock_);
- if (enabled_) {
- *sync_point = sync_point_manager_->GenerateSyncPoint();
-
- scoped_ptr<GpuChannelMessage> msg(new GpuChannelMessage(message));
- msg->retire_sync_point = retire_sync_point;
- msg->sync_point = *sync_point;
-
- PushMessageHelper(std::move(msg));
- return true;
- }
- return false;
-}
-
-bool GpuChannelMessageQueue::HasQueuedMessages() const {
- base::AutoLock auto_lock(channel_messages_lock_);
- return !channel_messages_.empty();
-}
-
-base::TimeTicks GpuChannelMessageQueue::GetNextMessageTimeTick() const {
- base::AutoLock auto_lock(channel_messages_lock_);
- if (!channel_messages_.empty())
- return channel_messages_.front()->time_received;
- return base::TimeTicks();
-}
-
-GpuChannelMessage* GpuChannelMessageQueue::GetNextMessage() const {
- base::AutoLock auto_lock(channel_messages_lock_);
- if (!channel_messages_.empty()) {
- DCHECK_GT(channel_messages_.front()->order_number,
- sync_point_order_data_->processed_order_num());
- DCHECK_LE(channel_messages_.front()->order_number,
- sync_point_order_data_->unprocessed_order_num());
-
- return channel_messages_.front();
- }
- return nullptr;
-}
-
-void GpuChannelMessageQueue::BeginMessageProcessing(
- const GpuChannelMessage* msg) {
- sync_point_order_data_->BeginProcessingOrderNumber(msg->order_number);
-}
-
-void GpuChannelMessageQueue::PauseMessageProcessing(
- const GpuChannelMessage* msg) {
- sync_point_order_data_->PauseProcessingOrderNumber(msg->order_number);
-}
-
-bool GpuChannelMessageQueue::MessageProcessed() {
- base::AutoLock auto_lock(channel_messages_lock_);
- DCHECK(!channel_messages_.empty());
- scoped_ptr<GpuChannelMessage> msg(channel_messages_.front());
- channel_messages_.pop_front();
- sync_point_order_data_->FinishProcessingOrderNumber(msg->order_number);
- return !channel_messages_.empty();
-}
-
-void GpuChannelMessageQueue::DeleteAndDisableMessages() {
- {
- base::AutoLock auto_lock(channel_messages_lock_);
- DCHECK(enabled_);
- enabled_ = false;
- }
-
- // We guarantee that the queues will no longer be modified after enabled_
- // is set to false, it is now safe to modify the queue without the lock.
- // All public facing modifying functions check enabled_ while all
- // private modifying functions DCHECK(enabled_) to enforce this.
- while (!channel_messages_.empty()) {
- scoped_ptr<GpuChannelMessage> msg(channel_messages_.front());
- channel_messages_.pop_front();
- // This needs to clean up both GpuCommandBufferMsg_InsertSyncPoint and
- // GpuCommandBufferMsg_RetireSyncPoint messages, safer to just check
- // if we have a sync point number here.
- if (msg->sync_point)
- sync_point_manager_->RetireSyncPoint(msg->sync_point);
- }
-
- if (sync_point_order_data_) {
- sync_point_order_data_->Destroy();
- sync_point_order_data_ = nullptr;
- }
-}
-
-void GpuChannelMessageQueue::ScheduleHandleMessage() {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&GpuChannel::HandleMessage, gpu_channel_));
-}
-
-void GpuChannelMessageQueue::PushMessageHelper(
- scoped_ptr<GpuChannelMessage> msg) {
- channel_messages_lock_.AssertAcquired();
- DCHECK(enabled_);
-
- msg->order_number = sync_point_order_data_->GenerateUnprocessedOrderNumber(
- sync_point_manager_);
- msg->time_received = base::TimeTicks::Now();
-
- bool had_messages = !channel_messages_.empty();
- channel_messages_.push_back(msg.release());
- if (!had_messages)
- ScheduleHandleMessage();
-}
-
-GpuChannelMessageFilter::GpuChannelMessageFilter(
- const base::WeakPtr<GpuChannel>& gpu_channel,
- GpuChannelMessageQueue* message_queue,
- base::SingleThreadTaskRunner* task_runner,
- gpu::PreemptionFlag* preempting_flag,
- bool future_sync_points)
- : preemption_state_(IDLE),
- gpu_channel_(gpu_channel),
- message_queue_(message_queue),
- sender_(nullptr),
- peer_pid_(base::kNullProcessId),
- task_runner_(task_runner),
- preempting_flag_(preempting_flag),
- a_stub_is_descheduled_(false),
- future_sync_points_(future_sync_points) {}
-
-GpuChannelMessageFilter::~GpuChannelMessageFilter() {}
-
-void GpuChannelMessageFilter::OnFilterAdded(IPC::Sender* sender) {
- DCHECK(!sender_);
- sender_ = sender;
- timer_ = make_scoped_ptr(new base::OneShotTimer);
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- filter->OnFilterAdded(sender_);
- }
-}
-
-void GpuChannelMessageFilter::OnFilterRemoved() {
- DCHECK(sender_);
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- filter->OnFilterRemoved();
- }
- sender_ = nullptr;
- peer_pid_ = base::kNullProcessId;
- timer_ = nullptr;
-}
-
-void GpuChannelMessageFilter::OnChannelConnected(int32_t peer_pid) {
- DCHECK(peer_pid_ == base::kNullProcessId);
- peer_pid_ = peer_pid;
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- filter->OnChannelConnected(peer_pid);
- }
-}
-
-void GpuChannelMessageFilter::OnChannelError() {
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- filter->OnChannelError();
- }
-}
-
-void GpuChannelMessageFilter::OnChannelClosing() {
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- filter->OnChannelClosing();
- }
-}
-
-void GpuChannelMessageFilter::AddChannelFilter(
- scoped_refptr<IPC::MessageFilter> filter) {
- channel_filters_.push_back(filter);
- if (sender_)
- filter->OnFilterAdded(sender_);
- if (peer_pid_ != base::kNullProcessId)
- filter->OnChannelConnected(peer_pid_);
-}
-
-void GpuChannelMessageFilter::RemoveChannelFilter(
- scoped_refptr<IPC::MessageFilter> filter) {
- if (sender_)
- filter->OnFilterRemoved();
- channel_filters_.erase(
- std::find(channel_filters_.begin(), channel_filters_.end(), filter));
-}
-
-bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
- DCHECK(sender_);
-
- if (message.should_unblock() || message.is_reply()) {
- DLOG(ERROR) << "Unexpected message type";
- return true;
- }
-
- if (message.type() == GpuChannelMsg_Nop::ID) {
- IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
- Send(reply);
- return true;
- }
-
- for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) {
- if (filter->OnMessageReceived(message)) {
- return true;
- }
- }
-
- bool handled = false;
- if ((message.type() == GpuCommandBufferMsg_RetireSyncPoint::ID) &&
- !future_sync_points_) {
- DLOG(ERROR) << "Untrusted client should not send "
- "GpuCommandBufferMsg_RetireSyncPoint message";
- return true;
- }
-
- if (message.type() == GpuCommandBufferMsg_InsertSyncPoint::ID) {
- base::Tuple<bool> params;
- IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
- if (!GpuCommandBufferMsg_InsertSyncPoint::ReadSendParam(&message,
- &params)) {
- reply->set_reply_error();
- Send(reply);
- return true;
- }
- bool retire_sync_point = base::get<0>(params);
- if (!future_sync_points_ && !retire_sync_point) {
- DLOG(ERROR) << "Untrusted contexts can't create future sync points";
- reply->set_reply_error();
- Send(reply);
- return true;
- }
-
- // Message queue must handle the entire sync point generation because the
- // message queue could be disabled from the main thread during generation.
- uint32_t sync_point = 0u;
- if (!message_queue_->GenerateSyncPointMessage(message, retire_sync_point,
- &sync_point)) {
- DLOG(ERROR) << "GpuChannel has been destroyed.";
- reply->set_reply_error();
- Send(reply);
- return true;
- }
-
- DCHECK_NE(sync_point, 0u);
- GpuCommandBufferMsg_InsertSyncPoint::WriteReplyParams(reply, sync_point);
- Send(reply);
- handled = true;
- }
-
- // Forward all other messages to the GPU Channel.
- if (!handled) {
- if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID ||
- message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&GpuChannel::HandleOutOfOrderMessage,
- gpu_channel_, message));
- } else {
- message_queue_->PushBackMessage(message);
- }
- handled = true;
- }
-
- UpdatePreemptionState();
- return handled;
-}
-
-void GpuChannelMessageFilter::OnMessageProcessed() {
- UpdatePreemptionState();
-}
-
-void GpuChannelMessageFilter::UpdateStubSchedulingState(
- bool a_stub_is_descheduled) {
- a_stub_is_descheduled_ = a_stub_is_descheduled;
- UpdatePreemptionState();
-}
-
-bool GpuChannelMessageFilter::Send(IPC::Message* message) {
- return sender_->Send(message);
-}
-
-void GpuChannelMessageFilter::UpdatePreemptionState() {
- switch (preemption_state_) {
- case IDLE:
- if (preempting_flag_.get() && message_queue_->HasQueuedMessages())
- TransitionToWaiting();
- break;
- case WAITING:
- // A timer will transition us to CHECKING.
- DCHECK(timer_->IsRunning());
- break;
- case CHECKING: {
- base::TimeTicks time_tick = message_queue_->GetNextMessageTimeTick();
- if (!time_tick.is_null()) {
- base::TimeDelta time_elapsed = base::TimeTicks::Now() - time_tick;
- if (time_elapsed.InMilliseconds() < kPreemptWaitTimeMs) {
- // Schedule another check for when the IPC may go long.
- timer_->Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kPreemptWaitTimeMs) -
- time_elapsed,
- this, &GpuChannelMessageFilter::UpdatePreemptionState);
- } else {
- if (a_stub_is_descheduled_)
- TransitionToWouldPreemptDescheduled();
- else
- TransitionToPreempting();
- }
- }
- } break;
- case PREEMPTING:
- // A TransitionToIdle() timer should always be running in this state.
- DCHECK(timer_->IsRunning());
- if (a_stub_is_descheduled_)
- TransitionToWouldPreemptDescheduled();
- else
- TransitionToIdleIfCaughtUp();
- break;
- case WOULD_PREEMPT_DESCHEDULED:
- // A TransitionToIdle() timer should never be running in this state.
- DCHECK(!timer_->IsRunning());
- if (!a_stub_is_descheduled_)
- TransitionToPreempting();
- else
- TransitionToIdleIfCaughtUp();
- break;
- default:
- NOTREACHED();
- }
-}
-
-void GpuChannelMessageFilter::TransitionToIdleIfCaughtUp() {
- DCHECK(preemption_state_ == PREEMPTING ||
- preemption_state_ == WOULD_PREEMPT_DESCHEDULED);
- base::TimeTicks next_tick = message_queue_->GetNextMessageTimeTick();
- if (next_tick.is_null()) {
- TransitionToIdle();
- } else {
- base::TimeDelta time_elapsed = base::TimeTicks::Now() - next_tick;
- if (time_elapsed.InMilliseconds() < kStopPreemptThresholdMs)
- TransitionToIdle();
- }
-}
-
-void GpuChannelMessageFilter::TransitionToIdle() {
- DCHECK(preemption_state_ == PREEMPTING ||
- preemption_state_ == WOULD_PREEMPT_DESCHEDULED);
- // Stop any outstanding timer set to force us from PREEMPTING to IDLE.
- timer_->Stop();
-
- preemption_state_ = IDLE;
- preempting_flag_->Reset();
- TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0);
-
- UpdatePreemptionState();
-}
-
-void GpuChannelMessageFilter::TransitionToWaiting() {
- DCHECK_EQ(preemption_state_, IDLE);
- DCHECK(!timer_->IsRunning());
-
- preemption_state_ = WAITING;
- timer_->Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kPreemptWaitTimeMs), this,
- &GpuChannelMessageFilter::TransitionToChecking);
-}
-
-void GpuChannelMessageFilter::TransitionToChecking() {
- DCHECK_EQ(preemption_state_, WAITING);
- DCHECK(!timer_->IsRunning());
-
- preemption_state_ = CHECKING;
- max_preemption_time_ = base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs);
- UpdatePreemptionState();
-}
-
-void GpuChannelMessageFilter::TransitionToPreempting() {
- DCHECK(preemption_state_ == CHECKING ||
- preemption_state_ == WOULD_PREEMPT_DESCHEDULED);
- DCHECK(!a_stub_is_descheduled_);
-
- // Stop any pending state update checks that we may have queued
- // while CHECKING.
- if (preemption_state_ == CHECKING)
- timer_->Stop();
-
- preemption_state_ = PREEMPTING;
- preempting_flag_->Set();
- TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 1);
-
- timer_->Start(FROM_HERE, max_preemption_time_, this,
- &GpuChannelMessageFilter::TransitionToIdle);
-
- UpdatePreemptionState();
-}
-
-void GpuChannelMessageFilter::TransitionToWouldPreemptDescheduled() {
- DCHECK(preemption_state_ == CHECKING || preemption_state_ == PREEMPTING);
- DCHECK(a_stub_is_descheduled_);
-
- if (preemption_state_ == CHECKING) {
- // Stop any pending state update checks that we may have queued
- // while CHECKING.
- timer_->Stop();
- } else {
- // Stop any TransitionToIdle() timers that we may have queued
- // while PREEMPTING.
- timer_->Stop();
- max_preemption_time_ = timer_->desired_run_time() - base::TimeTicks::Now();
- if (max_preemption_time_ < base::TimeDelta()) {
- TransitionToIdle();
- return;
- }
- }
-
- preemption_state_ = WOULD_PREEMPT_DESCHEDULED;
- preempting_flag_->Reset();
- TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0);
-
- UpdatePreemptionState();
-}
-
-GpuChannel::StreamState::StreamState(int32_t id, GpuStreamPriority priority)
- : id_(id), priority_(priority) {}
-
-GpuChannel::StreamState::~StreamState() {}
-
-void GpuChannel::StreamState::AddRoute(int32_t route_id) {
- routes_.insert(route_id);
-}
-void GpuChannel::StreamState::RemoveRoute(int32_t route_id) {
- routes_.erase(route_id);
-}
-
-bool GpuChannel::StreamState::HasRoute(int32_t route_id) const {
- return routes_.find(route_id) != routes_.end();
-}
-
-bool GpuChannel::StreamState::HasRoutes() const {
- return !routes_.empty();
-}
-
-GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
- gpu::SyncPointManager* sync_point_manager,
- GpuWatchdog* watchdog,
- gfx::GLShareGroup* share_group,
- gpu::gles2::MailboxManager* mailbox,
- gpu::PreemptionFlag* preempting_flag,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- int client_id,
- uint64_t client_tracing_id,
- bool allow_future_sync_points,
- bool allow_real_time_streams)
- : gpu_channel_manager_(gpu_channel_manager),
- sync_point_manager_(sync_point_manager),
- channel_id_(IPC::Channel::GenerateVerifiedChannelID("gpu")),
- preempting_flag_(preempting_flag),
- client_id_(client_id),
- client_tracing_id_(client_tracing_id),
- task_runner_(task_runner),
- io_task_runner_(io_task_runner),
- share_group_(share_group),
- mailbox_manager_(mailbox),
- subscription_ref_set_(new gpu::gles2::SubscriptionRefSet),
- pending_valuebuffer_state_(new gpu::ValueStateMap),
- watchdog_(watchdog),
- num_stubs_descheduled_(0),
- allow_future_sync_points_(allow_future_sync_points),
- allow_real_time_streams_(allow_real_time_streams),
- weak_factory_(this) {
- DCHECK(gpu_channel_manager);
- DCHECK(client_id);
-
- message_queue_ = GpuChannelMessageQueue::Create(
- weak_factory_.GetWeakPtr(), task_runner, sync_point_manager);
-
- filter_ = new GpuChannelMessageFilter(
- weak_factory_.GetWeakPtr(), message_queue_.get(), task_runner,
- preempting_flag, allow_future_sync_points);
-
- subscription_ref_set_->AddObserver(this);
-}
-
-GpuChannel::~GpuChannel() {
- // Clear stubs first because of dependencies.
- stubs_.clear();
-
- message_queue_->DeleteAndDisableMessages();
-
- subscription_ref_set_->RemoveObserver(this);
- if (preempting_flag_.get())
- preempting_flag_->Reset();
-}
-
-IPC::ChannelHandle GpuChannel::Init(base::WaitableEvent* shutdown_event) {
- DCHECK(shutdown_event);
- DCHECK(!channel_);
-
- IPC::ChannelHandle channel_handle(channel_id_);
-
- channel_ =
- IPC::SyncChannel::Create(channel_handle, IPC::Channel::MODE_SERVER, this,
- io_task_runner_, false, shutdown_event);
-
-#if defined(OS_POSIX)
- // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
- // that it gets closed after it has been sent.
- base::ScopedFD renderer_fd = channel_->TakeClientFileDescriptor();
- DCHECK(renderer_fd.is_valid());
- channel_handle.socket = base::FileDescriptor(std::move(renderer_fd));
-#endif
-
- channel_->AddFilter(filter_.get());
-
- return channel_handle;
-}
-
-base::ProcessId GpuChannel::GetClientPID() const {
- return channel_->GetPeerPID();
-}
-
-uint32_t GpuChannel::GetProcessedOrderNum() const {
- return message_queue_->GetProcessedOrderNum();
-}
-
-uint32_t GpuChannel::GetUnprocessedOrderNum() const {
- return message_queue_->GetUnprocessedOrderNum();
-}
-
-bool GpuChannel::OnMessageReceived(const IPC::Message& message) {
- // All messages should be pushed to channel_messages_ and handled separately.
- NOTREACHED();
- return false;
-}
-
-void GpuChannel::OnChannelError() {
- gpu_channel_manager_->RemoveChannel(client_id_);
-}
-
-bool GpuChannel::Send(IPC::Message* message) {
- // The GPU process must never send a synchronous IPC message to the renderer
- // process. This could result in deadlock.
- DCHECK(!message->is_sync());
-
- DVLOG(1) << "sending message @" << message << " on channel @" << this
- << " with type " << message->type();
-
- if (!channel_) {
- delete message;
- return false;
- }
-
- return channel_->Send(message);
-}
-
-void GpuChannel::OnAddSubscription(unsigned int target) {
- gpu_channel_manager()->Send(
- new GpuHostMsg_AddSubscription(client_id_, target));
-}
-
-void GpuChannel::OnRemoveSubscription(unsigned int target) {
- gpu_channel_manager()->Send(
- new GpuHostMsg_RemoveSubscription(client_id_, target));
-}
-
-void GpuChannel::OnStubSchedulingChanged(GpuCommandBufferStub* stub,
- bool scheduled) {
- bool a_stub_was_descheduled = num_stubs_descheduled_ > 0;
- if (scheduled) {
- num_stubs_descheduled_--;
- ScheduleHandleMessage();
- } else {
- num_stubs_descheduled_++;
- }
- DCHECK_LE(num_stubs_descheduled_, stubs_.size());
- bool a_stub_is_descheduled = num_stubs_descheduled_ > 0;
-
- if (a_stub_is_descheduled != a_stub_was_descheduled) {
- if (preempting_flag_.get()) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GpuChannelMessageFilter::UpdateStubSchedulingState,
- filter_, a_stub_is_descheduled));
- }
- }
-}
-
-CreateCommandBufferResult GpuChannel::CreateViewCommandBuffer(
- const gfx::GLSurfaceHandle& window,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id) {
- TRACE_EVENT1("gpu", "GpuChannel::CreateViewCommandBuffer", "route_id",
- route_id);
-
- int32_t share_group_id = init_params.share_group_id;
- GpuCommandBufferStub* share_group = stubs_.get(share_group_id);
-
- if (!share_group && share_group_id != MSG_ROUTING_NONE)
- return CREATE_COMMAND_BUFFER_FAILED;
-
- int32_t stream_id = init_params.stream_id;
- GpuStreamPriority stream_priority = init_params.stream_priority;
-
- if (share_group && stream_id != share_group->stream_id())
- return CREATE_COMMAND_BUFFER_FAILED;
-
- if (!allow_real_time_streams_ &&
- stream_priority == GpuStreamPriority::REAL_TIME)
- return CREATE_COMMAND_BUFFER_FAILED;
-
- auto stream_it = streams_.find(stream_id);
- if (stream_it != streams_.end() &&
- stream_priority != GpuStreamPriority::INHERIT &&
- stream_priority != stream_it->second.priority()) {
- return CREATE_COMMAND_BUFFER_FAILED;
- }
-
- bool offscreen = false;
- scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub(
- this, sync_point_manager_, task_runner_.get(), share_group, window,
- mailbox_manager_.get(), preempted_flag_.get(),
- subscription_ref_set_.get(), pending_valuebuffer_state_.get(),
- gfx::Size(), disallowed_features_, init_params.attribs,
- init_params.gpu_preference, stream_id, route_id, offscreen, watchdog_,
- init_params.active_url));
-
- if (!router_.AddRoute(route_id, stub.get())) {
- DLOG(ERROR) << "GpuChannel::CreateViewCommandBuffer(): "
- "failed to add route";
- return CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST;
- }
-
- if (stream_it != streams_.end()) {
- stream_it->second.AddRoute(route_id);
- } else {
- StreamState stream(stream_id, stream_priority);
- stream.AddRoute(route_id);
- streams_.insert(std::make_pair(stream_id, stream));
- }
-
- stubs_.set(route_id, std::move(stub));
- return CREATE_COMMAND_BUFFER_SUCCEEDED;
-}
-
-GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32_t route_id) {
- return stubs_.get(route_id);
-}
-
-void GpuChannel::LoseAllContexts() {
- gpu_channel_manager_->LoseAllContexts();
-}
-
-void GpuChannel::MarkAllContextsLost() {
- for (auto& kv : stubs_)
- kv.second->MarkContextLost();
-}
-
-bool GpuChannel::AddRoute(int32_t route_id, IPC::Listener* listener) {
- return router_.AddRoute(route_id, listener);
-}
-
-void GpuChannel::RemoveRoute(int32_t route_id) {
- router_.RemoveRoute(route_id);
-}
-
-void GpuChannel::SetPreemptByFlag(
- scoped_refptr<gpu::PreemptionFlag> preempted_flag) {
- DCHECK(stubs_.empty());
- preempted_flag_ = preempted_flag;
-}
-
-void GpuChannel::OnDestroy() {
- TRACE_EVENT0("gpu", "GpuChannel::OnDestroy");
- gpu_channel_manager_->RemoveChannel(client_id_);
-}
-
-bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
- IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer,
- OnCreateOffscreenCommandBuffer)
- IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
- OnDestroyCommandBuffer)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuMsg_CreateJpegDecoder,
- OnCreateJpegDecoder)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled) << msg.type();
- return handled;
-}
-
-scoped_refptr<gpu::SyncPointOrderData> GpuChannel::GetSyncPointOrderData() {
- return message_queue_->GetSyncPointOrderData();
-}
-
-void GpuChannel::HandleMessage() {
- // If we have been preempted by another channel, just post a task to wake up.
- if (preempted_flag_ && preempted_flag_->IsSet()) {
- ScheduleHandleMessage();
- return;
- }
-
- GpuChannelMessage* m = message_queue_->GetNextMessage();
-
- // TODO(sunnyps): This could be a DCHECK maybe?
- if (!m)
- return;
-
- const IPC::Message& message = m->message;
- message_queue_->BeginMessageProcessing(m);
- int32_t routing_id = message.routing_id();
- GpuCommandBufferStub* stub = stubs_.get(routing_id);
-
- DCHECK(!stub || stub->IsScheduled());
-
- DVLOG(1) << "received message @" << &message << " on channel @" << this
- << " with type " << message.type();
-
- bool handled = false;
-
- if (routing_id == MSG_ROUTING_CONTROL) {
- handled = OnControlMessageReceived(message);
- } else if (message.type() == GpuCommandBufferMsg_InsertSyncPoint::ID) {
- // TODO(dyen): Temporary handling of old sync points.
- // This must ensure that the sync point will be retired. Normally we'll
- // find the stub based on the routing ID, and associate the sync point
- // with it, but if that fails for any reason (channel or stub already
- // deleted, invalid routing id), we need to retire the sync point
- // immediately.
- if (stub) {
- stub->InsertSyncPoint(m->sync_point, m->retire_sync_point);
- } else {
- sync_point_manager_->RetireSyncPoint(m->sync_point);
- }
- handled = true;
- } else {
- handled = router_.RouteMessage(message);
- }
-
- // Respond to sync messages even if router failed to route.
- if (!handled && message.is_sync()) {
- IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
- reply->set_reply_error();
- Send(reply);
- handled = true;
- }
-
- // A command buffer may be descheduled or preempted but only in the middle of
- // a flush. In this case we should not pop the message from the queue.
- if (stub && stub->HasUnprocessedCommands()) {
- DCHECK_EQ((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID, message.type());
- message_queue_->PauseMessageProcessing(m);
- // If the stub is still scheduled then we were preempted and need to
- // schedule a wakeup otherwise some other event will wake us up e.g. sync
- // point completion. No DCHECK for preemption flag because that can change
- // any time.
- if (stub->IsScheduled())
- ScheduleHandleMessage();
- return;
- }
-
- if (message_queue_->MessageProcessed())
- ScheduleHandleMessage();
-
- if (preempting_flag_) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GpuChannelMessageFilter::OnMessageProcessed, filter_));
- }
-}
-
-void GpuChannel::ScheduleHandleMessage() {
- task_runner_->PostTask(FROM_HERE, base::Bind(&GpuChannel::HandleMessage,
- weak_factory_.GetWeakPtr()));
-}
-
-void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) {
- switch (msg.type()) {
- case GpuCommandBufferMsg_WaitForGetOffsetInRange::ID:
- case GpuCommandBufferMsg_WaitForTokenInRange::ID:
- router_.RouteMessage(msg);
- break;
- default:
- NOTREACHED();
- }
-}
-
-#if defined(OS_ANDROID)
-const GpuCommandBufferStub* GpuChannel::GetOneStub() const {
- for (const auto& kv : stubs_) {
- const GpuCommandBufferStub* stub = kv.second;
- if (stub->decoder() && !stub->decoder()->WasContextLost())
- return stub;
- }
- return nullptr;
-}
-#endif
-
-void GpuChannel::OnCreateOffscreenCommandBuffer(
- const gfx::Size& size,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id,
- bool* succeeded) {
- TRACE_EVENT1("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer", "route_id",
- route_id);
-
- int32_t share_group_id = init_params.share_group_id;
- GpuCommandBufferStub* share_group = stubs_.get(share_group_id);
-
- if (!share_group && share_group_id != MSG_ROUTING_NONE) {
- *succeeded = false;
- return;
- }
-
- int32_t stream_id = init_params.stream_id;
- GpuStreamPriority stream_priority = init_params.stream_priority;
-
- if (share_group && stream_id != share_group->stream_id()) {
- *succeeded = false;
- return;
- }
-
- if (!allow_real_time_streams_ &&
- stream_priority == GpuStreamPriority::REAL_TIME) {
- *succeeded = false;
- return;
- }
-
- auto stream_it = streams_.find(stream_id);
- if (stream_it != streams_.end() &&
- stream_priority != GpuStreamPriority::INHERIT &&
- stream_priority != stream_it->second.priority()) {
- *succeeded = false;
- return;
- }
-
- bool offscreen = true;
- scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub(
- this, sync_point_manager_, task_runner_.get(), share_group,
- gfx::GLSurfaceHandle(), mailbox_manager_.get(), preempted_flag_.get(),
- subscription_ref_set_.get(), pending_valuebuffer_state_.get(), size,
- disallowed_features_, init_params.attribs, init_params.gpu_preference,
- init_params.stream_id, route_id, offscreen, watchdog_,
- init_params.active_url));
-
- if (!router_.AddRoute(route_id, stub.get())) {
- DLOG(ERROR) << "GpuChannel::OnCreateOffscreenCommandBuffer(): "
- "failed to add route";
- *succeeded = false;
- return;
- }
-
- if (stream_it != streams_.end()) {
- stream_it->second.AddRoute(route_id);
- } else {
- StreamState stream(stream_id, stream_priority);
- stream.AddRoute(route_id);
- streams_.insert(std::make_pair(stream_id, stream));
- }
-
- stubs_.set(route_id, std::move(stub));
- *succeeded = true;
-}
-
-void GpuChannel::OnDestroyCommandBuffer(int32_t route_id) {
- TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer",
- "route_id", route_id);
-
- scoped_ptr<GpuCommandBufferStub> stub = stubs_.take_and_erase(route_id);
-
- if (!stub)
- return;
-
- router_.RemoveRoute(route_id);
-
- int32_t stream_id = stub->stream_id();
- auto stream_it = streams_.find(stream_id);
- DCHECK(stream_it != streams_.end());
- stream_it->second.RemoveRoute(route_id);
- if (!stream_it->second.HasRoutes())
- streams_.erase(stream_it);
-
- // In case the renderer is currently blocked waiting for a sync reply from the
- // stub, we need to make sure to reschedule the GpuChannel here.
- if (!stub->IsScheduled()) {
- // This stub won't get a chance to reschedule, so update the count now.
- OnStubSchedulingChanged(stub.get(), true);
- }
-}
-
-void GpuChannel::OnCreateJpegDecoder(int32_t route_id,
- IPC::Message* reply_msg) {
- if (!jpeg_decoder_) {
- jpeg_decoder_.reset(new GpuJpegDecodeAccelerator(this, io_task_runner_));
- }
- jpeg_decoder_->AddClient(route_id, reply_msg);
-}
-
-void GpuChannel::CacheShader(const std::string& key,
- const std::string& shader) {
- gpu_channel_manager_->Send(
- new GpuHostMsg_CacheShader(client_id_, key, shader));
-}
-
-void GpuChannel::AddFilter(IPC::MessageFilter* filter) {
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelMessageFilter::AddChannelFilter,
- filter_, make_scoped_refptr(filter)));
-}
-
-void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) {
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter,
- filter_, make_scoped_refptr(filter)));
-}
-
-uint64_t GpuChannel::GetMemoryUsage() {
- // Collect the unique memory trackers in use by the |stubs_|.
- std::set<gpu::gles2::MemoryTracker*> unique_memory_trackers;
- for (auto& kv : stubs_)
- unique_memory_trackers.insert(kv.second->GetMemoryTracker());
-
- // Sum the memory usage for all unique memory trackers.
- uint64_t size = 0;
- for (auto* tracker : unique_memory_trackers) {
- size += gpu_channel_manager()->gpu_memory_manager()->GetTrackerMemoryUsage(
- tracker);
- }
-
- return size;
-}
-
-scoped_refptr<gl::GLImage> GpuChannel::CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- uint32_t internalformat) {
- switch (handle.type) {
- case gfx::SHARED_MEMORY_BUFFER: {
- if (!base::IsValueInRangeForNumericType<size_t>(handle.stride))
- return nullptr;
- scoped_refptr<gl::GLImageSharedMemory> image(
- new gl::GLImageSharedMemory(size, internalformat));
- if (!image->Initialize(handle.handle, handle.id, format, handle.offset,
- handle.stride)) {
- return nullptr;
- }
-
- return image;
- }
- default: {
- GpuChannelManager* manager = gpu_channel_manager();
- if (!manager->gpu_memory_buffer_factory())
- return nullptr;
-
- return manager->gpu_memory_buffer_factory()
- ->AsImageFactory()
- ->CreateImageForGpuMemoryBuffer(handle,
- size,
- format,
- internalformat,
- client_id_);
- }
- }
-}
-
-void GpuChannel::HandleUpdateValueState(
- unsigned int target, const gpu::ValueState& state) {
- pending_valuebuffer_state_->UpdateState(target, state);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_channel.h b/chromium/content/common/gpu/gpu_channel.h
deleted file mode 100644
index 319f81d40ed..00000000000
--- a/chromium/content/common/gpu/gpu_channel.h
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_CHANNEL_H_
-#define CONTENT_COMMON_GPU_GPU_CHANNEL_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/process/process.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
-#include "content/common/gpu/gpu_memory_manager.h"
-#include "content/common/gpu/gpu_result_codes.h"
-#include "content/common/gpu/gpu_stream_priority.h"
-#include "content/common/message_router.h"
-#include "gpu/command_buffer/service/valuebuffer_manager.h"
-#include "ipc/ipc_sync_channel.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_share_group.h"
-#include "ui/gl/gpu_preference.h"
-
-struct GPUCreateCommandBufferConfig;
-
-namespace base {
-class WaitableEvent;
-}
-
-namespace gpu {
-class PreemptionFlag;
-class SyncPointOrderData;
-class SyncPointManager;
-union ValueState;
-class ValueStateMap;
-namespace gles2 {
-class SubscriptionRefSet;
-}
-}
-
-namespace IPC {
-class MessageFilter;
-}
-
-namespace content {
-class GpuChannelManager;
-class GpuChannelMessageFilter;
-class GpuChannelMessageQueue;
-class GpuJpegDecodeAccelerator;
-class GpuWatchdog;
-
-// Encapsulates an IPC channel between the GPU process and one renderer
-// process. On the renderer side there's a corresponding GpuChannelHost.
-class CONTENT_EXPORT GpuChannel
- : public IPC::Listener,
- public IPC::Sender,
- public gpu::gles2::SubscriptionRefSet::Observer {
- public:
- // Takes ownership of the renderer process handle.
- GpuChannel(GpuChannelManager* gpu_channel_manager,
- gpu::SyncPointManager* sync_point_manager,
- GpuWatchdog* watchdog,
- gfx::GLShareGroup* share_group,
- gpu::gles2::MailboxManager* mailbox_manager,
- gpu::PreemptionFlag* preempting_flag,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- int client_id,
- uint64_t client_tracing_id,
- bool allow_future_sync_points,
- bool allow_real_time_streams);
- ~GpuChannel() override;
-
- // Initializes the IPC channel. Caller takes ownership of the client FD in
- // the returned handle and is responsible for closing it.
- virtual IPC::ChannelHandle Init(base::WaitableEvent* shutdown_event);
-
- // Get the GpuChannelManager that owns this channel.
- GpuChannelManager* gpu_channel_manager() const {
- return gpu_channel_manager_;
- }
-
- const std::string& channel_id() const { return channel_id_; }
-
- virtual base::ProcessId GetClientPID() const;
-
- int client_id() const { return client_id_; }
-
- uint64_t client_tracing_id() const { return client_tracing_id_; }
-
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() const {
- return io_task_runner_;
- }
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& msg) override;
- void OnChannelError() override;
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* msg) override;
-
- // SubscriptionRefSet::Observer implementation
- void OnAddSubscription(unsigned int target) override;
- void OnRemoveSubscription(unsigned int target) override;
-
- // This is called when a command buffer transitions between scheduled and
- // descheduled states. When any stub is descheduled, we stop preempting
- // other channels.
- void OnStubSchedulingChanged(GpuCommandBufferStub* stub, bool scheduled);
-
- CreateCommandBufferResult CreateViewCommandBuffer(
- const gfx::GLSurfaceHandle& window,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id);
-
- gfx::GLShareGroup* share_group() const { return share_group_.get(); }
-
- GpuCommandBufferStub* LookupCommandBuffer(int32_t route_id);
-
- void LoseAllContexts();
- void MarkAllContextsLost();
-
- // Called to add a listener for a particular message routing ID.
- // Returns true if succeeded.
- bool AddRoute(int32_t route_id, IPC::Listener* listener);
-
- // Called to remove a listener for a particular message routing ID.
- void RemoveRoute(int32_t route_id);
-
- void SetPreemptingFlag(gpu::PreemptionFlag* flag);
-
- // If |preemption_flag->IsSet()|, any stub on this channel
- // should stop issuing GL commands. Setting this to NULL stops deferral.
- void SetPreemptByFlag(
- scoped_refptr<gpu::PreemptionFlag> preemption_flag);
-
- void CacheShader(const std::string& key, const std::string& shader);
-
- void AddFilter(IPC::MessageFilter* filter);
- void RemoveFilter(IPC::MessageFilter* filter);
-
- uint64_t GetMemoryUsage();
-
- scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- uint32_t internalformat);
-
- bool allow_future_sync_points() const { return allow_future_sync_points_; }
-
- void HandleUpdateValueState(unsigned int target,
- const gpu::ValueState& state);
-
- // Visible for testing.
- const gpu::ValueStateMap* pending_valuebuffer_state() const {
- return pending_valuebuffer_state_.get();
- }
-
- // Visible for testing.
- GpuChannelMessageFilter* filter() const { return filter_.get(); }
-
- // Returns the global order number for the last processed IPC message.
- uint32_t GetProcessedOrderNum() const;
-
- // Returns the global order number for the last unprocessed IPC message.
- uint32_t GetUnprocessedOrderNum() const;
-
- // Returns the shared sync point global order data.
- scoped_refptr<gpu::SyncPointOrderData> GetSyncPointOrderData();
-
- void HandleMessage();
-
- // Some messages such as WaitForGetOffsetInRange and WaitForTokenInRange are
- // processed as soon as possible because the client is blocked until they
- // are completed.
- void HandleOutOfOrderMessage(const IPC::Message& msg);
-
-#if defined(OS_ANDROID)
- const GpuCommandBufferStub* GetOneStub() const;
-#endif
-
- protected:
- // The message filter on the io thread.
- scoped_refptr<GpuChannelMessageFilter> filter_;
-
- // Map of routing id to command buffer stub.
- base::ScopedPtrHashMap<int32_t, scoped_ptr<GpuCommandBufferStub>> stubs_;
-
- private:
- class StreamState {
- public:
- StreamState(int32_t id, GpuStreamPriority priority);
- ~StreamState();
-
- int32_t id() const { return id_; }
- GpuStreamPriority priority() const { return priority_; }
-
- void AddRoute(int32_t route_id);
- void RemoveRoute(int32_t route_id);
- bool HasRoute(int32_t route_id) const;
- bool HasRoutes() const;
-
- private:
- int32_t id_;
- GpuStreamPriority priority_;
- base::hash_set<int32_t> routes_;
- };
-
- void OnDestroy();
-
- bool OnControlMessageReceived(const IPC::Message& msg);
-
- void ScheduleHandleMessage();
-
- // Message handlers.
- void OnCreateOffscreenCommandBuffer(
- const gfx::Size& size,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id,
- bool* succeeded);
- void OnDestroyCommandBuffer(int32_t route_id);
- void OnCreateJpegDecoder(int32_t route_id, IPC::Message* reply_msg);
-
- // The lifetime of objects of this class is managed by a GpuChannelManager.
- // The GpuChannelManager destroy all the GpuChannels that they own when they
- // are destroyed. So a raw pointer is safe.
- GpuChannelManager* gpu_channel_manager_;
-
- // Sync point manager. Outlives the channel and is guaranteed to outlive the
- // message loop.
- gpu::SyncPointManager* sync_point_manager_;
-
- scoped_ptr<IPC::SyncChannel> channel_;
-
- // Uniquely identifies the channel within this GPU process.
- std::string channel_id_;
-
- // Used to implement message routing functionality to CommandBuffer objects
- MessageRouter router_;
-
- // Whether the processing of IPCs on this channel is stalled and we should
- // preempt other GpuChannels.
- scoped_refptr<gpu::PreemptionFlag> preempting_flag_;
-
- // If non-NULL, all stubs on this channel should stop processing GL
- // commands (via their GpuScheduler) when preempted_flag_->IsSet()
- scoped_refptr<gpu::PreemptionFlag> preempted_flag_;
-
- scoped_refptr<GpuChannelMessageQueue> message_queue_;
-
- // The id of the client who is on the other side of the channel.
- int client_id_;
-
- // The tracing ID used for memory allocations associated with this client.
- uint64_t client_tracing_id_;
-
- // The task runners for the main thread and the io thread.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- // The share group that all contexts associated with a particular renderer
- // process use.
- scoped_refptr<gfx::GLShareGroup> share_group_;
-
- scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
-
- scoped_refptr<gpu::gles2::SubscriptionRefSet> subscription_ref_set_;
-
- scoped_refptr<gpu::ValueStateMap> pending_valuebuffer_state_;
-
- scoped_ptr<GpuJpegDecodeAccelerator> jpeg_decoder_;
-
- gpu::gles2::DisallowedFeatures disallowed_features_;
- GpuWatchdog* watchdog_;
-
- size_t num_stubs_descheduled_;
-
- // Map of stream id to stream state.
- base::hash_map<int32_t, StreamState> streams_;
-
- bool allow_future_sync_points_;
- bool allow_real_time_streams_;
-
- // Member variables should appear before the WeakPtrFactory, to ensure
- // that any WeakPtrs to Controller are invalidated before its members
- // variable's destructors are executed, rendering them invalid.
- base::WeakPtrFactory<GpuChannel> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuChannel);
-};
-
-// This filter does three things:
-// - it counts and timestamps each message forwarded to the channel
-// so that we can preempt other channels if a message takes too long to
-// process. To guarantee fairness, we must wait a minimum amount of time
-// before preempting and we limit the amount of time that we can preempt in
-// one shot (see constants above).
-// - it handles the GpuCommandBufferMsg_InsertSyncPoint message on the IO
-// thread, generating the sync point ID and responding immediately, and then
-// posting a task to insert the GpuCommandBufferMsg_RetireSyncPoint message
-// into the channel's queue.
-// - it generates mailbox names for clients of the GPU process on the IO thread.
-class GpuChannelMessageFilter : public IPC::MessageFilter {
- public:
- GpuChannelMessageFilter(const base::WeakPtr<GpuChannel>& gpu_channel,
- GpuChannelMessageQueue* message_queue,
- base::SingleThreadTaskRunner* task_runner,
- gpu::PreemptionFlag* preempting_flag,
- bool future_sync_points);
-
- // IPC::MessageFilter implementation.
- void OnFilterAdded(IPC::Sender* sender) override;
- void OnFilterRemoved() override;
- void OnChannelConnected(int32_t peer_pid) override;
- void OnChannelError() override;
- void OnChannelClosing() override;
- bool OnMessageReceived(const IPC::Message& message) override;
-
- void AddChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
- void RemoveChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
-
- void OnMessageProcessed();
-
- void UpdateStubSchedulingState(bool a_stub_is_descheduled);
-
- bool Send(IPC::Message* message);
-
- protected:
- ~GpuChannelMessageFilter() override;
-
- private:
- enum PreemptionState {
- // Either there's no other channel to preempt, there are no messages
- // pending processing, or we just finished preempting and have to wait
- // before preempting again.
- IDLE,
- // We are waiting kPreemptWaitTimeMs before checking if we should preempt.
- WAITING,
- // We can preempt whenever any IPC processing takes more than
- // kPreemptWaitTimeMs.
- CHECKING,
- // We are currently preempting (i.e. no stub is descheduled).
- PREEMPTING,
- // We would like to preempt, but some stub is descheduled.
- WOULD_PREEMPT_DESCHEDULED,
- };
-
- void UpdatePreemptionState();
-
- void TransitionToIdleIfCaughtUp();
- void TransitionToIdle();
- void TransitionToWaiting();
- void TransitionToChecking();
- void TransitionToPreempting();
- void TransitionToWouldPreemptDescheduled();
-
- PreemptionState preemption_state_;
-
- // Maximum amount of time that we can spend in PREEMPTING.
- // It is reset when we transition to IDLE.
- base::TimeDelta max_preemption_time_;
-
- base::WeakPtr<GpuChannel> gpu_channel_;
- // The message_queue_ is used to handle messages on the main thread.
- scoped_refptr<GpuChannelMessageQueue> message_queue_;
- IPC::Sender* sender_;
- base::ProcessId peer_pid_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- scoped_refptr<gpu::PreemptionFlag> preempting_flag_;
- std::vector<scoped_refptr<IPC::MessageFilter>> channel_filters_;
-
- // This timer is created and destroyed on the IO thread.
- scoped_ptr<base::OneShotTimer> timer_;
-
- bool a_stub_is_descheduled_;
-
- // True if this channel can create future sync points.
- bool future_sync_points_;
-};
-
-struct GpuChannelMessage {
- uint32_t order_number;
- base::TimeTicks time_received;
- IPC::Message message;
-
- // TODO(dyen): Temporary sync point data, remove once new sync point lands.
- bool retire_sync_point;
- uint32_t sync_point;
-
- GpuChannelMessage(const IPC::Message& msg)
- : order_number(0),
- time_received(base::TimeTicks()),
- message(msg),
- retire_sync_point(false),
- sync_point(0) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuChannelMessage);
-};
-
-class GpuChannelMessageQueue
- : public base::RefCountedThreadSafe<GpuChannelMessageQueue> {
- public:
- static scoped_refptr<GpuChannelMessageQueue> Create(
- const base::WeakPtr<GpuChannel>& gpu_channel,
- base::SingleThreadTaskRunner* task_runner,
- gpu::SyncPointManager* sync_point_manager);
-
- scoped_refptr<gpu::SyncPointOrderData> GetSyncPointOrderData();
-
- // Returns the global order number for the last unprocessed IPC message.
- uint32_t GetUnprocessedOrderNum() const;
-
- // Returns the global order number for the last unprocessed IPC message.
- uint32_t GetProcessedOrderNum() const;
-
- bool HasQueuedMessages() const;
-
- base::TimeTicks GetNextMessageTimeTick() const;
-
- GpuChannelMessage* GetNextMessage() const;
-
- // Should be called before a message begins to be processed.
- void BeginMessageProcessing(const GpuChannelMessage* msg);
-
- // Should be called if a message began processing but did not finish.
- void PauseMessageProcessing(const GpuChannelMessage* msg);
-
- // Should be called after a message returned by GetNextMessage is processed.
- // Returns true if there are more messages on the queue.
- bool MessageProcessed();
-
- void PushBackMessage(const IPC::Message& message);
-
- bool GenerateSyncPointMessage(const IPC::Message& message,
- bool retire_sync_point,
- uint32_t* sync_point_number);
-
- void DeleteAndDisableMessages();
-
- private:
- friend class base::RefCountedThreadSafe<GpuChannelMessageQueue>;
-
- GpuChannelMessageQueue(const base::WeakPtr<GpuChannel>& gpu_channel,
- base::SingleThreadTaskRunner* task_runner,
- gpu::SyncPointManager* sync_point_manager);
- ~GpuChannelMessageQueue();
-
- void ScheduleHandleMessage();
-
- void PushMessageHelper(scoped_ptr<GpuChannelMessage> msg);
-
- bool enabled_;
-
- // Both deques own the messages.
- std::deque<GpuChannelMessage*> channel_messages_;
-
- // This lock protects enabled_ and channel_messages_.
- mutable base::Lock channel_messages_lock_;
-
- // Keeps track of sync point related state such as message order numbers.
- scoped_refptr<gpu::SyncPointOrderData> sync_point_order_data_;
-
- base::WeakPtr<GpuChannel> gpu_channel_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- gpu::SyncPointManager* sync_point_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageQueue);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_CHANNEL_H_
diff --git a/chromium/content/common/gpu/gpu_channel_manager.cc b/chromium/content/common/gpu/gpu_channel_manager.cc
deleted file mode 100644
index 8f59e90345d..00000000000
--- a/chromium/content/common/gpu/gpu_channel_manager.cc
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_channel_manager.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
-#include "content/common/gpu/gpu_memory_manager.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/message_router.h"
-#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/common/value_state.h"
-#include "gpu/command_buffer/service/feature_info.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/memory_program_cache.h"
-#include "gpu/command_buffer/service/shader_translator_cache.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "ipc/message_filter.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_share_group.h"
-
-#if defined(OS_CHROMEOS)
-#include "content/common/gpu/media/gpu_arc_video_service.h"
-#endif
-
-namespace content {
-
-namespace {
-#if defined(OS_ANDROID)
-// Amount of time we expect the GPU to stay powered up without being used.
-const int kMaxGpuIdleTimeMs = 40;
-// Maximum amount of time we keep pinging the GPU waiting for the client to
-// draw.
-const int kMaxKeepAliveTimeMs = 200;
-#endif
-
-}
-
-GpuChannelManager::GpuChannelManager(
- IPC::SyncChannel* channel,
- GpuWatchdog* watchdog,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- base::WaitableEvent* shutdown_event,
- gpu::SyncPointManager* sync_point_manager,
- GpuMemoryBufferFactory* gpu_memory_buffer_factory)
- : task_runner_(task_runner),
- io_task_runner_(io_task_runner),
- channel_(channel),
- watchdog_(watchdog),
- shutdown_event_(shutdown_event),
- share_group_(new gfx::GLShareGroup),
- mailbox_manager_(gpu::gles2::MailboxManager::Create()),
- gpu_memory_manager_(this),
- sync_point_manager_(sync_point_manager),
- sync_point_client_waiter_(
- sync_point_manager->CreateSyncPointClientWaiter()),
- gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
- weak_factory_(this) {
- DCHECK(task_runner);
- DCHECK(io_task_runner);
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
- preemption_flag_ = new gpu::PreemptionFlag;
-}
-
-GpuChannelManager::~GpuChannelManager() {
- // Destroy channels before anything else because of dependencies.
- gpu_channels_.clear();
- if (default_offscreen_surface_.get()) {
- default_offscreen_surface_->Destroy();
- default_offscreen_surface_ = NULL;
- }
-}
-
-gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
- if (!program_cache_.get() &&
- (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
- gfx::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuProgramCache)) {
- program_cache_.reset(new gpu::gles2::MemoryProgramCache());
- }
- return program_cache_.get();
-}
-
-gpu::gles2::ShaderTranslatorCache*
-GpuChannelManager::shader_translator_cache() {
- if (!shader_translator_cache_.get())
- shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
- return shader_translator_cache_.get();
-}
-
-gpu::gles2::FramebufferCompletenessCache*
-GpuChannelManager::framebuffer_completeness_cache() {
- if (!framebuffer_completeness_cache_.get())
- framebuffer_completeness_cache_ =
- new gpu::gles2::FramebufferCompletenessCache;
- return framebuffer_completeness_cache_.get();
-}
-
-void GpuChannelManager::RemoveChannel(int client_id) {
- Send(new GpuHostMsg_DestroyChannel(client_id));
- gpu_channels_.erase(client_id);
-}
-
-int GpuChannelManager::GenerateRouteID() {
- static int last_id = 0;
- return ++last_id;
-}
-
-void GpuChannelManager::AddRoute(int32_t routing_id, IPC::Listener* listener) {
- router_.AddRoute(routing_id, listener);
-}
-
-void GpuChannelManager::RemoveRoute(int32_t routing_id) {
- router_.RemoveRoute(routing_id);
-}
-
-GpuChannel* GpuChannelManager::LookupChannel(int32_t client_id) const {
- const auto& it = gpu_channels_.find(client_id);
- return it != gpu_channels_.end() ? it->second : nullptr;
-}
-
-bool GpuChannelManager::OnControlMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
- IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
- IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
- IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
- OnCreateViewCommandBuffer)
- IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
-#if defined(OS_CHROMEOS)
- IPC_MESSAGE_HANDLER(GpuMsg_CreateArcVideoAcceleratorChannel,
- OnCreateArcVideoAcceleratorChannel)
-#endif
- IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
- IPC_MESSAGE_HANDLER(GpuMsg_UpdateValueState, OnUpdateValueState)
-#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(GpuMsg_WakeUpGpu, OnWakeUpGpu);
-#endif
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
- if (msg.routing_id() == MSG_ROUTING_CONTROL)
- return OnControlMessageReceived(msg);
-
- return router_.RouteMessage(msg);
-}
-
-bool GpuChannelManager::Send(IPC::Message* msg) {
- return channel_->Send(msg);
-}
-
-scoped_ptr<GpuChannel> GpuChannelManager::CreateGpuChannel(
- int client_id,
- uint64_t client_tracing_id,
- bool preempts,
- bool allow_future_sync_points,
- bool allow_real_time_streams) {
- return make_scoped_ptr(new GpuChannel(
- this, sync_point_manager(), watchdog_, share_group(), mailbox_manager(),
- preempts ? preemption_flag() : nullptr, task_runner_.get(),
- io_task_runner_.get(), client_id, client_tracing_id,
- allow_future_sync_points, allow_real_time_streams));
-}
-
-void GpuChannelManager::OnEstablishChannel(
- const GpuMsg_EstablishChannel_Params& params) {
- DCHECK(!params.preempts || !params.preempted);
- scoped_ptr<GpuChannel> channel(CreateGpuChannel(
- params.client_id, params.client_tracing_id, params.preempts,
- params.allow_future_sync_points, params.allow_real_time_streams));
- if (params.preempted)
- channel->SetPreemptByFlag(preemption_flag_.get());
- IPC::ChannelHandle channel_handle = channel->Init(shutdown_event_);
-
- gpu_channels_.set(params.client_id, std::move(channel));
-
- Send(new GpuHostMsg_ChannelEstablished(channel_handle));
-}
-
-void GpuChannelManager::OnCloseChannel(
- const IPC::ChannelHandle& channel_handle) {
- for (auto it = gpu_channels_.begin(); it != gpu_channels_.end(); ++it) {
- if (it->second->channel_id() == channel_handle.name) {
- gpu_channels_.erase(it);
- return;
- }
- }
-}
-
-void GpuChannelManager::OnCreateViewCommandBuffer(
- const gfx::GLSurfaceHandle& window,
- int32_t client_id,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id) {
- CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
-
- auto it = gpu_channels_.find(client_id);
- if (it != gpu_channels_.end()) {
- result = it->second->CreateViewCommandBuffer(window, init_params, route_id);
- }
-
- Send(new GpuHostMsg_CommandBufferCreated(result));
-}
-
-void GpuChannelManager::DestroyGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- int client_id) {
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
- base::Unretained(this), id, client_id));
-}
-
-void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
- gfx::GpuMemoryBufferId id,
- int client_id) {
- gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id);
-}
-
-void GpuChannelManager::OnDestroyGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- int client_id,
- const gpu::SyncToken& sync_token) {
- if (sync_token.HasData()) {
- scoped_refptr<gpu::SyncPointClientState> release_state =
- sync_point_manager()->GetSyncPointClientState(
- sync_token.namespace_id(), sync_token.command_buffer_id());
- if (release_state) {
- sync_point_client_waiter_->WaitOutOfOrder(
- release_state.get(), sync_token.release_count(),
- base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
- base::Unretained(this), id, client_id));
- return;
- }
- }
-
- // No sync token or invalid sync token, destroy immediately.
- DestroyGpuMemoryBuffer(id, client_id);
-}
-
-#if defined(OS_CHROMEOS)
-void GpuChannelManager::OnCreateArcVideoAcceleratorChannel() {
- if (!gpu_arc_video_service_) {
- gpu_arc_video_service_.reset(
- new GpuArcVideoService(shutdown_event_, io_task_runner_));
- }
-
- gpu_arc_video_service_->CreateChannel(
- base::Bind(&GpuChannelManager::ArcVideoAcceleratorChannelCreated,
- weak_factory_.GetWeakPtr()));
-}
-
-void GpuChannelManager::ArcVideoAcceleratorChannelCreated(
- const IPC::ChannelHandle& handle) {
- Send(new GpuHostMsg_ArcVideoAcceleratorChannelCreated(handle));
-}
-
-void GpuChannelManager::OnShutdownArcVideoService() {
- gpu_arc_video_service_.reset();
-}
-#endif
-
-void GpuChannelManager::OnUpdateValueState(
- int client_id, unsigned int target, const gpu::ValueState& state) {
- // Only pass updated state to the channel corresponding to the
- // render_widget_host where the event originated.
- auto it = gpu_channels_.find(client_id);
- if (it != gpu_channels_.end())
- it->second->HandleUpdateValueState(target, state);
-}
-
-void GpuChannelManager::OnLoadedShader(const std::string& program_proto) {
- if (program_cache())
- program_cache()->LoadProgram(program_proto);
-}
-
-uint32_t GpuChannelManager::GetUnprocessedOrderNum() const {
- uint32_t unprocessed_order_num = 0;
- for (auto& kv : gpu_channels_) {
- unprocessed_order_num =
- std::max(unprocessed_order_num, kv.second->GetUnprocessedOrderNum());
- }
- return unprocessed_order_num;
-}
-
-uint32_t GpuChannelManager::GetProcessedOrderNum() const {
- uint32_t processed_order_num = 0;
- for (auto& kv : gpu_channels_) {
- processed_order_num =
- std::max(processed_order_num, kv.second->GetProcessedOrderNum());
- }
- return processed_order_num;
-}
-
-void GpuChannelManager::LoseAllContexts() {
- for (auto& kv : gpu_channels_) {
- kv.second->MarkAllContextsLost();
- }
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&GpuChannelManager::OnLoseAllContexts,
- weak_factory_.GetWeakPtr()));
-}
-
-void GpuChannelManager::OnLoseAllContexts() {
- gpu_channels_.clear();
-}
-
-gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
- if (!default_offscreen_surface_.get()) {
- default_offscreen_surface_ =
- gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
- }
- return default_offscreen_surface_.get();
-}
-
-#if defined(OS_ANDROID)
-void GpuChannelManager::DidAccessGpu() {
- last_gpu_access_time_ = base::TimeTicks::Now();
-}
-
-void GpuChannelManager::OnWakeUpGpu() {
- begin_wake_up_time_ = base::TimeTicks::Now();
- ScheduleWakeUpGpu();
-}
-
-void GpuChannelManager::ScheduleWakeUpGpu() {
- base::TimeTicks now = base::TimeTicks::Now();
- TRACE_EVENT2("gpu", "GpuChannelManager::ScheduleWakeUp",
- "idle_time", (now - last_gpu_access_time_).InMilliseconds(),
- "keep_awake_time", (now - begin_wake_up_time_).InMilliseconds());
- if (now - last_gpu_access_time_ <
- base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs))
- return;
- if (now - begin_wake_up_time_ >
- base::TimeDelta::FromMilliseconds(kMaxKeepAliveTimeMs))
- return;
-
- DoWakeUpGpu();
-
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE, base::Bind(&GpuChannelManager::ScheduleWakeUpGpu,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs));
-}
-
-void GpuChannelManager::DoWakeUpGpu() {
- const GpuCommandBufferStub* stub = nullptr;
- for (const auto& kv : gpu_channels_) {
- const GpuChannel* channel = kv.second;
- stub = channel->GetOneStub();
- if (stub) {
- DCHECK(stub->decoder());
- break;
- }
- }
- if (!stub || !stub->decoder()->MakeCurrent())
- return;
- glFinish();
- DidAccessGpu();
-}
-#endif
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_channel_manager.h b/chromium/content/common/gpu/gpu_channel_manager.h
deleted file mode 100644
index f195a55c27e..00000000000
--- a/chromium/content/common/gpu/gpu_channel_manager.h
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_CHANNEL_MANAGER_H_
-#define CONTENT_COMMON_GPU_GPU_CHANNEL_MANAGER_H_
-
-#include <stdint.h>
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "content/common/content_param_traits.h"
-#include "content/common/gpu/gpu_memory_manager.h"
-#include "content/common/message_router.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_sender.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_surface.h"
-
-namespace base {
-class WaitableEvent;
-}
-
-namespace gfx {
-class GLShareGroup;
-}
-
-namespace gpu {
-class PreemptionFlag;
-class SyncPointClient;
-class SyncPointManager;
-struct SyncToken;
-union ValueState;
-namespace gles2 {
-class FramebufferCompletenessCache;
-class MailboxManager;
-class ProgramCache;
-class ShaderTranslatorCache;
-}
-}
-
-namespace IPC {
-struct ChannelHandle;
-class SyncChannel;
-}
-
-struct GPUCreateCommandBufferConfig;
-struct GpuMsg_EstablishChannel_Params;
-
-namespace content {
-#if defined(OS_CHROMEOS)
-class GpuArcVideoService;
-#endif
-class GpuChannel;
-class GpuMemoryBufferFactory;
-class GpuWatchdog;
-
-// A GpuChannelManager is a thread responsible for issuing rendering commands
-// managing the lifetimes of GPU channels and forwarding IPC requests from the
-// browser process to them based on the corresponding renderer ID.
-class CONTENT_EXPORT GpuChannelManager : public IPC::Listener,
- public IPC::Sender {
- public:
- GpuChannelManager(IPC::SyncChannel* channel,
- GpuWatchdog* watchdog,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- base::WaitableEvent* shutdown_event,
- gpu::SyncPointManager* sync_point_manager,
- GpuMemoryBufferFactory* gpu_memory_buffer_factory);
- ~GpuChannelManager() override;
-
- // Remove the channel for a particular renderer.
- void RemoveChannel(int client_id);
-
- // Listener overrides.
- bool OnMessageReceived(const IPC::Message& msg) override;
-
- // Sender overrides.
- bool Send(IPC::Message* msg) override;
-
- void LoseAllContexts();
-
- int GenerateRouteID();
- void AddRoute(int32_t routing_id, IPC::Listener* listener);
- void RemoveRoute(int32_t routing_id);
-
- gpu::gles2::ProgramCache* program_cache();
- gpu::gles2::ShaderTranslatorCache* shader_translator_cache();
- gpu::gles2::FramebufferCompletenessCache* framebuffer_completeness_cache();
-
- GpuMemoryManager* gpu_memory_manager() { return &gpu_memory_manager_; }
-
- GpuChannel* LookupChannel(int32_t client_id) const;
-
- gfx::GLSurface* GetDefaultOffscreenSurface();
-
- GpuMemoryBufferFactory* gpu_memory_buffer_factory() {
- return gpu_memory_buffer_factory_;
- }
-
- // Returns the maximum order number for unprocessed IPC messages across all
- // channels.
- uint32_t GetUnprocessedOrderNum() const;
-
- // Returns the maximum order number for processed IPC messages across all
- // channels.
- uint32_t GetProcessedOrderNum() const;
-
-#if defined(OS_ANDROID)
- void DidAccessGpu();
-#endif
-
- protected:
- virtual scoped_ptr<GpuChannel> CreateGpuChannel(int client_id,
- uint64_t client_tracing_id,
- bool preempts,
- bool allow_future_sync_points,
- bool allow_real_time_streams);
-
- gpu::SyncPointManager* sync_point_manager() const {
- return sync_point_manager_;
- }
-
- gfx::GLShareGroup* share_group() const { return share_group_.get(); }
- gpu::gles2::MailboxManager* mailbox_manager() const {
- return mailbox_manager_.get();
- }
- gpu::PreemptionFlag* preemption_flag() const {
- return preemption_flag_.get();
- }
-
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- // These objects manage channels to individual renderer processes there is
- // one channel for each renderer process that has connected to this GPU
- // process.
- base::ScopedPtrHashMap<int32_t, scoped_ptr<GpuChannel>> gpu_channels_;
-
- private:
- // Message handlers.
- bool OnControlMessageReceived(const IPC::Message& msg);
- void OnEstablishChannel(const GpuMsg_EstablishChannel_Params& params);
- void OnCloseChannel(const IPC::ChannelHandle& channel_handle);
- void OnVisibilityChanged(int32_t render_view_id,
- int32_t client_id,
- bool visible);
- void OnCreateViewCommandBuffer(
- const gfx::GLSurfaceHandle& window,
- int32_t client_id,
- const GPUCreateCommandBufferConfig& init_params,
- int32_t route_id);
- void OnLoadedShader(const std::string& shader);
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id);
- void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id, int client_id);
- void OnDestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id,
- const gpu::SyncToken& sync_token);
-#if defined(OS_CHROMEOS)
- void OnCreateArcVideoAcceleratorChannel();
- void ArcVideoAcceleratorChannelCreated(const IPC::ChannelHandle& handle);
- void OnShutdownArcVideoService();
-#endif
-
- void OnUpdateValueState(int client_id,
- unsigned int target,
- const gpu::ValueState& state);
-#if defined(OS_ANDROID)
- void OnWakeUpGpu();
- void ScheduleWakeUpGpu();
- void DoWakeUpGpu();
-#endif
- void OnLoseAllContexts();
-
- // Used to send and receive IPC messages from the browser process.
- IPC::SyncChannel* const channel_;
- MessageRouter router_;
-
- GpuWatchdog* watchdog_;
-
- base::WaitableEvent* shutdown_event_;
-
- scoped_refptr<gfx::GLShareGroup> share_group_;
- scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
- scoped_refptr<gpu::PreemptionFlag> preemption_flag_;
- GpuMemoryManager gpu_memory_manager_;
- // SyncPointManager guaranteed to outlive running MessageLoop.
- gpu::SyncPointManager* sync_point_manager_;
- scoped_ptr<gpu::SyncPointClient> sync_point_client_waiter_;
- scoped_ptr<gpu::gles2::ProgramCache> program_cache_;
- scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
- scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
- framebuffer_completeness_cache_;
- scoped_refptr<gfx::GLSurface> default_offscreen_surface_;
-#if defined(OS_CHROMEOS)
- scoped_ptr<GpuArcVideoService> gpu_arc_video_service_;
-#endif
- GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
-#if defined(OS_ANDROID)
- // Last time we know the GPU was powered on. Global for tracking across all
- // transport surfaces.
- base::TimeTicks last_gpu_access_time_;
- base::TimeTicks begin_wake_up_time_;
-#endif
-
- // Member variables should appear before the WeakPtrFactory, to ensure
- // that any WeakPtrs to Controller are invalidated before its members
- // variable's destructors are executed, rendering them invalid.
- base::WeakPtrFactory<GpuChannelManager> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuChannelManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_CHANNEL_MANAGER_H_
diff --git a/chromium/content/common/gpu/gpu_channel_manager_unittest.cc b/chromium/content/common/gpu/gpu_channel_manager_unittest.cc
deleted file mode 100644
index bef694808e8..00000000000
--- a/chromium/content/common/gpu/gpu_channel_manager_unittest.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2014 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 <stddef.h>
-#include <stdint.h>
-
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_channel_test_common.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "gpu/command_buffer/common/value_state.h"
-#include "gpu/command_buffer/service/gl_utils.h"
-#include "gpu/command_buffer/service/valuebuffer_manager.h"
-#include "ipc/ipc_test_sink.h"
-
-using gpu::gles2::ValuebufferManager;
-using gpu::ValueState;
-
-namespace content {
-
-class GpuChannelManagerTest : public GpuChannelTestCommon {
- public:
- GpuChannelManagerTest() : GpuChannelTestCommon() {}
- ~GpuChannelManagerTest() override {}
-};
-
-TEST_F(GpuChannelManagerTest, EstablishChannel) {
- int32_t kClientId = 1;
- uint64_t kClientTracingId = 1;
-
- ASSERT_TRUE(channel_manager());
-
- GpuMsg_EstablishChannel_Params params;
- params.client_id = kClientId;
- params.client_tracing_id = kClientTracingId;
- params.preempts = false;
- params.preempted = false;
- params.allow_future_sync_points = false;
- params.allow_real_time_streams = false;
- EXPECT_TRUE(
- channel_manager()->OnMessageReceived(GpuMsg_EstablishChannel(params)));
- EXPECT_EQ((size_t)1, sink()->message_count());
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_ChannelEstablished::ID);
- ASSERT_TRUE(msg);
- base::Tuple<IPC::ChannelHandle> handle;
- ASSERT_TRUE(GpuHostMsg_ChannelEstablished::Read(msg, &handle));
- EXPECT_NE("", base::get<0>(handle).name);
- sink()->ClearMessages();
-
- GpuChannel* channel = channel_manager()->LookupChannel(kClientId);
- ASSERT_TRUE(channel);
- EXPECT_EQ(base::get<0>(handle).name, channel->channel_id());
-}
-
-TEST_F(GpuChannelManagerTest, SecureValueStateForwarding) {
- int32_t kClientId1 = 111;
- uint64_t kClientTracingId1 = 11111;
- int32_t kClientId2 = 222;
- uint64_t kClientTracingId2 = 22222;
- ValueState value_state1;
- value_state1.int_value[0] = 1111;
- value_state1.int_value[1] = 0;
- value_state1.int_value[2] = 0;
- value_state1.int_value[3] = 0;
- ValueState value_state2;
- value_state2.int_value[0] = 3333;
- value_state2.int_value[1] = 0;
- value_state2.int_value[2] = 0;
- value_state2.int_value[3] = 0;
-
- ASSERT_TRUE(channel_manager());
-
- // Initialize gpu channels
- GpuMsg_EstablishChannel_Params params;
- params.client_id = kClientId1;
- params.client_tracing_id = kClientTracingId1;
- params.preempts = false;
- params.preempted = false;
- params.allow_future_sync_points = false;
- params.allow_real_time_streams = false;
- EXPECT_TRUE(
- channel_manager()->OnMessageReceived(GpuMsg_EstablishChannel(params)));
- GpuChannel* channel1 = channel_manager()->LookupChannel(kClientId1);
- ASSERT_TRUE(channel1);
-
- params.client_id = kClientId2;
- params.client_tracing_id = kClientTracingId2;
- EXPECT_TRUE(
- channel_manager()->OnMessageReceived(GpuMsg_EstablishChannel(params)));
- GpuChannel* channel2 = channel_manager()->LookupChannel(kClientId2);
- ASSERT_TRUE(channel2);
-
- EXPECT_NE(channel1, channel2);
-
- // Make sure value states are only accessible by proper channels
- channel_manager()->OnMessageReceived(GpuMsg_UpdateValueState(
- kClientId1, GL_MOUSE_POSITION_CHROMIUM, value_state1));
- channel_manager()->OnMessageReceived(GpuMsg_UpdateValueState(
- kClientId2, GL_MOUSE_POSITION_CHROMIUM, value_state2));
-
- const gpu::ValueStateMap* pending_value_buffer_state1 =
- channel1->pending_valuebuffer_state();
- const gpu::ValueStateMap* pending_value_buffer_state2 =
- channel2->pending_valuebuffer_state();
- EXPECT_NE(pending_value_buffer_state1, pending_value_buffer_state2);
-
- const ValueState* state1 =
- pending_value_buffer_state1->GetState(GL_MOUSE_POSITION_CHROMIUM);
- const ValueState* state2 =
- pending_value_buffer_state2->GetState(GL_MOUSE_POSITION_CHROMIUM);
- EXPECT_NE(state1, state2);
-
- EXPECT_EQ(state1->int_value[0], value_state1.int_value[0]);
- EXPECT_EQ(state2->int_value[0], value_state2.int_value[0]);
- EXPECT_NE(state1->int_value[0], state2->int_value[0]);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_channel_test_common.cc b/chromium/content/common/gpu/gpu_channel_test_common.cc
deleted file mode 100644
index 7fe03759fc9..00000000000
--- a/chromium/content/common/gpu/gpu_channel_test_common.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2015 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 "content/common/gpu/gpu_channel_test_common.h"
-
-#include "base/test/test_simple_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "ipc/ipc_test_sink.h"
-
-namespace content {
-
-TestGpuChannelManager::TestGpuChannelManager(
- IPC::TestSink* sink,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- gpu::SyncPointManager* sync_point_manager,
- GpuMemoryBufferFactory* gpu_memory_buffer_factory)
- : GpuChannelManager(nullptr,
- nullptr,
- task_runner,
- io_task_runner,
- nullptr,
- sync_point_manager,
- gpu_memory_buffer_factory),
- sink_(sink) {}
-
-TestGpuChannelManager::~TestGpuChannelManager() {
- // Clear gpu channels here so that any IPC messages sent are handled using the
- // overridden Send method.
- gpu_channels_.clear();
-}
-
-bool TestGpuChannelManager::Send(IPC::Message* msg) {
- return sink_->Send(msg);
-}
-
-scoped_ptr<GpuChannel> TestGpuChannelManager::CreateGpuChannel(
- int client_id,
- uint64_t client_tracing_id,
- bool preempts,
- bool allow_future_sync_points,
- bool allow_real_time_streams) {
- return make_scoped_ptr(new TestGpuChannel(
- sink_, this, sync_point_manager(), share_group(), mailbox_manager(),
- preempts ? preemption_flag() : nullptr, task_runner_.get(),
- io_task_runner_.get(), client_id, client_tracing_id,
- allow_future_sync_points, allow_real_time_streams));
-}
-
-TestGpuChannel::TestGpuChannel(IPC::TestSink* sink,
- GpuChannelManager* gpu_channel_manager,
- gpu::SyncPointManager* sync_point_manager,
- gfx::GLShareGroup* share_group,
- gpu::gles2::MailboxManager* mailbox_manager,
- gpu::PreemptionFlag* preempting_flag,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- int client_id,
- uint64_t client_tracing_id,
- bool allow_future_sync_points,
- bool allow_real_time_streams)
- : GpuChannel(gpu_channel_manager,
- sync_point_manager,
- nullptr,
- share_group,
- mailbox_manager,
- preempting_flag,
- task_runner,
- io_task_runner,
- client_id,
- client_tracing_id,
- allow_future_sync_points,
- allow_real_time_streams),
- sink_(sink) {}
-
-TestGpuChannel::~TestGpuChannel() {
- // Call stubs here so that any IPC messages sent are handled using the
- // overridden Send method.
- stubs_.clear();
-}
-
-base::ProcessId TestGpuChannel::GetClientPID() const {
- return base::kNullProcessId;
-}
-
-IPC::ChannelHandle TestGpuChannel::Init(base::WaitableEvent* shutdown_event) {
- filter_->OnFilterAdded(sink_);
- return IPC::ChannelHandle(channel_id());
-}
-
-bool TestGpuChannel::Send(IPC::Message* msg) {
- DCHECK(!msg->is_sync());
- return sink_->Send(msg);
-}
-
-// TODO(sunnyps): Use a mock memory buffer factory when necessary.
-GpuChannelTestCommon::GpuChannelTestCommon()
- : sink_(new IPC::TestSink),
- task_runner_(new base::TestSimpleTaskRunner),
- io_task_runner_(new base::TestSimpleTaskRunner),
- sync_point_manager_(new gpu::SyncPointManager(false)),
- channel_manager_(new TestGpuChannelManager(sink_.get(),
- task_runner_.get(),
- io_task_runner_.get(),
- sync_point_manager_.get(),
- nullptr)) {}
-
-GpuChannelTestCommon::~GpuChannelTestCommon() {}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_channel_test_common.h b/chromium/content/common/gpu/gpu_channel_test_common.h
deleted file mode 100644
index ed2243531dd..00000000000
--- a/chromium/content/common/gpu/gpu_channel_test_common.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2015 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 <stdint.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-class TestSimpleTaskRunner;
-} // namespace base
-
-namespace IPC {
-class TestSink;
-} // namespace IPC
-
-namespace content {
-
-class SyncPointManager;
-
-class TestGpuChannelManager : public GpuChannelManager {
- public:
- TestGpuChannelManager(IPC::TestSink* sink,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- gpu::SyncPointManager* sync_point_manager,
- GpuMemoryBufferFactory* gpu_memory_buffer_factory);
- ~TestGpuChannelManager() override;
-
- // IPC::Sender implementation.
- bool Send(IPC::Message* msg) override;
-
- protected:
- scoped_ptr<GpuChannel> CreateGpuChannel(
- int client_id,
- uint64_t client_tracing_id,
- bool preempts,
- bool allow_future_sync_points,
- bool allow_real_time_streams) override;
-
- private:
- IPC::TestSink* const sink_;
-};
-
-class TestGpuChannel : public GpuChannel {
- public:
- TestGpuChannel(IPC::TestSink* sink,
- GpuChannelManager* gpu_channel_manager,
- gpu::SyncPointManager* sync_point_manager,
- gfx::GLShareGroup* share_group,
- gpu::gles2::MailboxManager* mailbox_manager,
- gpu::PreemptionFlag* preempting_flag,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- int client_id,
- uint64_t client_tracing_id,
- bool allow_future_sync_points,
- bool allow_real_time_streams);
- ~TestGpuChannel() override;
-
- base::ProcessId GetClientPID() const override;
-
- IPC::ChannelHandle Init(base::WaitableEvent* shutdown_event) override;
-
- // IPC::Sender implementation.
- bool Send(IPC::Message* msg) override;
-
- private:
- IPC::TestSink* const sink_;
-};
-
-class GpuChannelTestCommon : public testing::Test {
- public:
- GpuChannelTestCommon();
- ~GpuChannelTestCommon() override;
-
- protected:
- IPC::TestSink* sink() { return sink_.get(); }
- GpuChannelManager* channel_manager() { return channel_manager_.get(); }
- base::TestSimpleTaskRunner* task_runner() { return task_runner_.get(); }
-
- private:
- scoped_ptr<IPC::TestSink> sink_;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
- scoped_refptr<base::TestSimpleTaskRunner> io_task_runner_;
- scoped_ptr<gpu::SyncPointManager> sync_point_manager_;
- scoped_ptr<GpuChannelManager> channel_manager_;
-};
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_channel_unittest.cc b/chromium/content/common/gpu/gpu_channel_unittest.cc
deleted file mode 100644
index d7a376aef76..00000000000
--- a/chromium/content/common/gpu/gpu_channel_unittest.cc
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright (c) 2015 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 <stdint.h>
-
-#include "base/test/test_simple_task_runner.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_channel_test_common.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ipc/ipc_test_sink.h"
-
-namespace content {
-
-class GpuChannelTest : public GpuChannelTestCommon {
- public:
- GpuChannelTest() : GpuChannelTestCommon() {}
- ~GpuChannelTest() override {}
-
- GpuChannel* CreateChannel(int32_t client_id, bool allow_real_time_streams) {
- DCHECK(channel_manager());
- uint64_t kClientTracingId = 1;
- GpuMsg_EstablishChannel_Params params;
- params.client_id = client_id;
- params.client_tracing_id = kClientTracingId;
- params.preempts = false;
- params.preempted = false;
- params.allow_future_sync_points = false;
- params.allow_real_time_streams = allow_real_time_streams;
- EXPECT_TRUE(
- channel_manager()->OnMessageReceived(GpuMsg_EstablishChannel(params)));
- return channel_manager()->LookupChannel(client_id);
- }
-};
-
-TEST_F(GpuChannelTest, CreateViewCommandBuffer) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
-
- gfx::GLSurfaceHandle surface_handle;
- int32_t kRouteId = 1;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = 0;
- init_params.stream_priority = GpuStreamPriority::NORMAL;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- surface_handle, kClientId, init_params, kRouteId));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- ASSERT_TRUE(stub);
-}
-
-TEST_F(GpuChannelTest, IncompatibleStreamIds) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
-
- // Create first context.
- int32_t kRouteId1 = 1;
- int32_t kStreamId1 = 1;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId1;
- init_params.stream_priority = GpuStreamPriority::NORMAL;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId1));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId1);
- ASSERT_TRUE(stub);
-
- // Create second context in same share group but different stream.
- int32_t kRouteId2 = 2;
- int32_t kStreamId2 = 2;
-
- init_params.share_group_id = kRouteId1;
- init_params.stream_id = kStreamId2;
- init_params.stream_priority = GpuStreamPriority::NORMAL;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId2));
-
- msg = sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_FAILED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- stub = channel->LookupCommandBuffer(kRouteId2);
- ASSERT_FALSE(stub);
-}
-
-TEST_F(GpuChannelTest, IncompatibleStreamPriorities) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
-
- // Create first context.
- int32_t kRouteId1 = 1;
- int32_t kStreamId1 = 1;
- GpuStreamPriority kStreamPriority1 = GpuStreamPriority::NORMAL;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId1;
- init_params.stream_priority = kStreamPriority1;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId1));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId1);
- ASSERT_TRUE(stub);
-
- // Create second context in same share group but different stream.
- int32_t kRouteId2 = 2;
- int32_t kStreamId2 = kStreamId1;
- GpuStreamPriority kStreamPriority2 = GpuStreamPriority::LOW;
-
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId2;
- init_params.stream_priority = kStreamPriority2;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId2));
-
- msg = sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_FAILED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- stub = channel->LookupCommandBuffer(kRouteId2);
- ASSERT_FALSE(stub);
-}
-
-TEST_F(GpuChannelTest, StreamLifetime) {
- int32_t kClientId = 1;
- GpuChannel* channel = CreateChannel(kClientId, false);
- ASSERT_TRUE(channel);
-
- // Create first context.
- int32_t kRouteId1 = 1;
- int32_t kStreamId1 = 1;
- GpuStreamPriority kStreamPriority1 = GpuStreamPriority::NORMAL;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId1;
- init_params.stream_priority = kStreamPriority1;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId1));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId1);
- ASSERT_TRUE(stub);
-
- {
- // GpuChannelHost always calls set_unblock(false) on messages sent to the
- // GPU process.
- IPC::Message m = GpuChannelMsg_DestroyCommandBuffer(kRouteId1);
- m.set_unblock(false);
- EXPECT_TRUE(channel->filter()->OnMessageReceived(m));
- task_runner()->RunPendingTasks();
- }
-
- stub = channel->LookupCommandBuffer(kRouteId1);
- ASSERT_FALSE(stub);
-
- // Create second context in same share group but different stream.
- int32_t kRouteId2 = 2;
- int32_t kStreamId2 = 2;
- GpuStreamPriority kStreamPriority2 = GpuStreamPriority::LOW;
-
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId2;
- init_params.stream_priority = kStreamPriority2;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId2));
-
- msg = sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- stub = channel->LookupCommandBuffer(kRouteId2);
- ASSERT_TRUE(stub);
-}
-
-TEST_F(GpuChannelTest, RealTimeStreamsDisallowed) {
- int32_t kClientId = 1;
- bool allow_real_time_streams = false;
- GpuChannel* channel = CreateChannel(kClientId, allow_real_time_streams);
- ASSERT_TRUE(channel);
-
- // Create first context.
- int32_t kRouteId = 1;
- int32_t kStreamId = 1;
- GpuStreamPriority kStreamPriority = GpuStreamPriority::REAL_TIME;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId;
- init_params.stream_priority = kStreamPriority;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_FAILED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- ASSERT_FALSE(stub);
-}
-
-TEST_F(GpuChannelTest, RealTimeStreamsAllowed) {
- int32_t kClientId = 1;
- bool allow_real_time_streams = true;
- GpuChannel* channel = CreateChannel(kClientId, allow_real_time_streams);
- ASSERT_TRUE(channel);
-
- // Create first context.
- int32_t kRouteId = 1;
- int32_t kStreamId = 1;
- GpuStreamPriority kStreamPriority = GpuStreamPriority::REAL_TIME;
- GPUCreateCommandBufferConfig init_params;
- init_params.share_group_id = MSG_ROUTING_NONE;
- init_params.stream_id = kStreamId;
- init_params.stream_priority = kStreamPriority;
- init_params.attribs = std::vector<int>();
- init_params.active_url = GURL();
- init_params.gpu_preference = gfx::PreferIntegratedGpu;
- channel_manager()->OnMessageReceived(GpuMsg_CreateViewCommandBuffer(
- gfx::GLSurfaceHandle(), kClientId, init_params, kRouteId));
-
- const IPC::Message* msg =
- sink()->GetUniqueMessageMatching(GpuHostMsg_CommandBufferCreated::ID);
- ASSERT_TRUE(msg);
-
- base::Tuple<CreateCommandBufferResult> result;
- ASSERT_TRUE(GpuHostMsg_CommandBufferCreated::Read(msg, &result));
-
- EXPECT_EQ(CREATE_COMMAND_BUFFER_SUCCEEDED, base::get<0>(result));
-
- sink()->ClearMessages();
-
- GpuCommandBufferStub* stub = channel->LookupCommandBuffer(kRouteId);
- ASSERT_TRUE(stub);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_command_buffer_stub.cc b/chromium/content/common/gpu/gpu_command_buffer_stub.cc
deleted file mode 100644
index 58bfa6a4fb9..00000000000
--- a/chromium/content/common/gpu/gpu_command_buffer_stub.cc
+++ /dev/null
@@ -1,1269 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_command_buffer_stub.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/hash.h"
-#include "base/json/json_writer.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_memory_manager.h"
-#include "content/common/gpu/gpu_memory_tracking.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/gpu_watchdog.h"
-#include "content/common/gpu/image_transport_surface.h"
-#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
-#include "content/common/gpu/media/gpu_video_encode_accelerator.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/common/constants.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "gpu/command_buffer/service/gl_context_virtual.h"
-#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "gpu/command_buffer/service/image_manager.h"
-#include "gpu/command_buffer/service/logger.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/command_buffer/service/query_manager.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "gpu/command_buffer/service/transfer_buffer_manager.h"
-#include "gpu/command_buffer/service/valuebuffer_manager.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_switches.h"
-
-#if defined(OS_WIN)
-#include "base/win/win_util.h"
-#include "content/public/common/sandbox_init.h"
-#endif
-
-#if defined(OS_ANDROID)
-#include "content/common/gpu/stream_texture_android.h"
-#endif
-
-namespace content {
-struct WaitForCommandState {
- WaitForCommandState(int32_t start, int32_t end, IPC::Message* reply)
- : start(start), end(end), reply(reply) {}
-
- int32_t start;
- int32_t end;
- scoped_ptr<IPC::Message> reply;
-};
-
-namespace {
-
-// The GpuCommandBufferMemoryTracker class provides a bridge between the
-// ContextGroup's memory type managers and the GpuMemoryManager class.
-class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker {
- public:
- explicit GpuCommandBufferMemoryTracker(GpuChannel* channel,
- uint64_t share_group_tracing_guid)
- : tracking_group_(
- channel->gpu_channel_manager()
- ->gpu_memory_manager()
- ->CreateTrackingGroup(channel->GetClientPID(), this)),
- client_tracing_id_(channel->client_tracing_id()),
- client_id_(channel->client_id()),
- share_group_tracing_guid_(share_group_tracing_guid) {}
-
- void TrackMemoryAllocatedChange(
- size_t old_size, size_t new_size) override {
- tracking_group_->TrackMemoryAllocatedChange(
- old_size, new_size);
- }
-
- bool EnsureGPUMemoryAvailable(size_t size_needed) override {
- return tracking_group_->EnsureGPUMemoryAvailable(size_needed);
- };
-
- uint64_t ClientTracingId() const override { return client_tracing_id_; }
- int ClientId() const override { return client_id_; }
- uint64_t ShareGroupTracingGUID() const override {
- return share_group_tracing_guid_;
- }
-
- private:
- ~GpuCommandBufferMemoryTracker() override {}
- scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
- const uint64_t client_tracing_id_;
- const int client_id_;
- const uint64_t share_group_tracing_guid_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
-};
-
-// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
-// url_hash matches.
-void FastSetActiveURL(const GURL& url, size_t url_hash) {
- // Leave the previously set URL in the empty case -- empty URLs are given by
- // BlinkPlatformImpl::createOffscreenGraphicsContext3D. Hopefully the
- // onscreen context URL was set previously and will show up even when a crash
- // occurs during offscreen command processing.
- if (url.is_empty())
- return;
- static size_t g_last_url_hash = 0;
- if (url_hash != g_last_url_hash) {
- g_last_url_hash = url_hash;
- GetContentClient()->SetActiveURL(url);
- }
-}
-
-// The first time polling a fence, delay some extra time to allow other
-// stubs to process some work, or else the timing of the fences could
-// allow a pattern of alternating fast and slow frames to occur.
-const int64_t kHandleMoreWorkPeriodMs = 2;
-const int64_t kHandleMoreWorkPeriodBusyMs = 1;
-
-// Prevents idle work from being starved.
-const int64_t kMaxTimeSinceIdleMs = 10;
-
-class DevToolsChannelData : public base::trace_event::ConvertableToTraceFormat {
- public:
- static scoped_refptr<base::trace_event::ConvertableToTraceFormat>
- CreateForChannel(GpuChannel* channel);
-
- void AppendAsTraceFormat(std::string* out) const override {
- std::string tmp;
- base::JSONWriter::Write(*value_, &tmp);
- *out += tmp;
- }
-
- private:
- explicit DevToolsChannelData(base::Value* value) : value_(value) {}
- ~DevToolsChannelData() override {}
- scoped_ptr<base::Value> value_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsChannelData);
-};
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-DevToolsChannelData::CreateForChannel(GpuChannel* channel) {
- scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue);
- res->SetInteger("renderer_pid", channel->GetClientPID());
- res->SetDouble("used_bytes", channel->GetMemoryUsage());
- return new DevToolsChannelData(res.release());
-}
-
-void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- const base::Closure& callback) {
- if (task_runner->BelongsToCurrentThread()) {
- callback.Run();
- } else {
- task_runner->PostTask(FROM_HERE, callback);
- }
-}
-
-uint64_t GetCommandBufferID(int channel_id, int32_t route_id) {
- return (static_cast<uint64_t>(channel_id) << 32) | route_id;
-}
-
-} // namespace
-
-GpuCommandBufferStub::GpuCommandBufferStub(
- GpuChannel* channel,
- gpu::SyncPointManager* sync_point_manager,
- base::SingleThreadTaskRunner* task_runner,
- GpuCommandBufferStub* share_group,
- const gfx::GLSurfaceHandle& handle,
- gpu::gles2::MailboxManager* mailbox_manager,
- gpu::PreemptionFlag* preempt_by_flag,
- gpu::gles2::SubscriptionRefSet* subscription_ref_set,
- gpu::ValueStateMap* pending_valuebuffer_state,
- const gfx::Size& size,
- const gpu::gles2::DisallowedFeatures& disallowed_features,
- const std::vector<int32_t>& attribs,
- gfx::GpuPreference gpu_preference,
- int32_t stream_id,
- int32_t route_id,
- bool offscreen,
- GpuWatchdog* watchdog,
- const GURL& active_url)
- : channel_(channel),
- sync_point_manager_(sync_point_manager),
- task_runner_(task_runner),
- initialized_(false),
- handle_(handle),
- initial_size_(size),
- disallowed_features_(disallowed_features),
- requested_attribs_(attribs),
- gpu_preference_(gpu_preference),
- use_virtualized_gl_context_(false),
- command_buffer_id_(GetCommandBufferID(channel->client_id(), route_id)),
- stream_id_(stream_id),
- route_id_(route_id),
- offscreen_(offscreen),
- last_flush_count_(0),
- watchdog_(watchdog),
- waiting_for_sync_point_(false),
- previous_processed_num_(0),
- preemption_flag_(preempt_by_flag),
- active_url_(active_url) {
- active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
- FastSetActiveURL(active_url_, active_url_hash_);
-
- gpu::gles2::ContextCreationAttribHelper attrib_parser;
- attrib_parser.Parse(requested_attribs_);
-
- if (share_group) {
- context_group_ = share_group->context_group_;
- DCHECK(context_group_->bind_generates_resource() ==
- attrib_parser.bind_generates_resource);
- } else {
- context_group_ = new gpu::gles2::ContextGroup(
- mailbox_manager,
- new GpuCommandBufferMemoryTracker(channel, command_buffer_id_),
- channel_->gpu_channel_manager()->shader_translator_cache(),
- channel_->gpu_channel_manager()->framebuffer_completeness_cache(), NULL,
- subscription_ref_set, pending_valuebuffer_state,
- attrib_parser.bind_generates_resource);
- }
-
-// Virtualize PreferIntegratedGpu contexts by default on OS X to prevent
-// performance regressions when enabling FCM.
-// http://crbug.com/180463
-#if defined(OS_MACOSX)
- if (gpu_preference_ == gfx::PreferIntegratedGpu)
- use_virtualized_gl_context_ = true;
-#endif
-
- use_virtualized_gl_context_ |=
- context_group_->feature_info()->workarounds().use_virtualized_gl_contexts;
-
- // MailboxManagerSync synchronization correctness currently depends on having
- // only a single context. See crbug.com/510243 for details.
- use_virtualized_gl_context_ |= mailbox_manager->UsesSync();
-
- if (offscreen && initial_size_.IsEmpty()) {
- // If we're an offscreen surface with zero width and/or height, set to a
- // non-zero size so that we have a complete framebuffer for operations like
- // glClear.
- initial_size_ = gfx::Size(1, 1);
- }
-}
-
-GpuCommandBufferStub::~GpuCommandBufferStub() {
- Destroy();
-}
-
-GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() const {
- return channel()->gpu_channel_manager()->gpu_memory_manager();
-}
-
-bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
- "GPUTask",
- "data",
- DevToolsChannelData::CreateForChannel(channel()));
- FastSetActiveURL(active_url_, active_url_hash_);
-
- bool have_context = false;
- // Ensure the appropriate GL context is current before handling any IPC
- // messages directed at the command buffer. This ensures that the message
- // handler can assume that the context is current (not necessary for
- // RetireSyncPoint or WaitSyncPoint).
- if (decoder_.get() &&
- message.type() != GpuCommandBufferMsg_SetGetBuffer::ID &&
- message.type() != GpuCommandBufferMsg_WaitForTokenInRange::ID &&
- message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID &&
- message.type() != GpuCommandBufferMsg_RegisterTransferBuffer::ID &&
- message.type() != GpuCommandBufferMsg_DestroyTransferBuffer::ID &&
- message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
- message.type() != GpuCommandBufferMsg_SignalSyncPoint::ID) {
- if (!MakeCurrent())
- return false;
- have_context = true;
- }
-
- // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
- // here. This is so the reply can be delayed if the scheduler is unscheduled.
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
- OnInitialize);
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
- OnSetGetBuffer);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ProduceFrontBuffer,
- OnProduceFrontBuffer);
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForTokenInRange,
- OnWaitForTokenInRange);
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForGetOffsetInRange,
- OnWaitForGetOffsetInRange);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
- OnRegisterTransferBuffer);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
- OnDestroyTransferBuffer);
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
- OnCreateVideoDecoder)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoEncoder,
- OnCreateVideoEncoder)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
- OnRetireSyncPoint)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
- OnSignalSyncPoint)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken,
- OnSignalSyncToken)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery,
- OnSignalQuery)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage);
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture,
- OnCreateStreamTexture)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- CheckCompleteWaits();
-
- // Ensure that any delayed work that was created will be handled.
- if (have_context) {
- if (scheduler_)
- scheduler_->ProcessPendingQueries();
- ScheduleDelayedWork(
- base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodMs));
- }
-
- DCHECK(handled);
- return handled;
-}
-
-bool GpuCommandBufferStub::Send(IPC::Message* message) {
- return channel_->Send(message);
-}
-
-bool GpuCommandBufferStub::IsScheduled() {
- return (!scheduler_.get() || scheduler_->scheduled());
-}
-
-void GpuCommandBufferStub::PollWork() {
- // Post another delayed task if we have not yet reached the time at which
- // we should process delayed work.
- base::TimeTicks current_time = base::TimeTicks::Now();
- DCHECK(!process_delayed_work_time_.is_null());
- if (process_delayed_work_time_ > current_time) {
- task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
- process_delayed_work_time_ - current_time);
- return;
- }
- process_delayed_work_time_ = base::TimeTicks();
-
- PerformWork();
-}
-
-void GpuCommandBufferStub::PerformWork() {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::PerformWork");
-
- FastSetActiveURL(active_url_, active_url_hash_);
- if (decoder_.get() && !MakeCurrent())
- return;
-
- if (scheduler_) {
- uint32_t current_unprocessed_num =
- channel()->gpu_channel_manager()->GetUnprocessedOrderNum();
- // We're idle when no messages were processed or scheduled.
- bool is_idle = (previous_processed_num_ == current_unprocessed_num);
- if (!is_idle && !last_idle_time_.is_null()) {
- base::TimeDelta time_since_idle =
- base::TimeTicks::Now() - last_idle_time_;
- base::TimeDelta max_time_since_idle =
- base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs);
-
- // Force idle when it's been too long since last time we were idle.
- if (time_since_idle > max_time_since_idle)
- is_idle = true;
- }
-
- if (is_idle) {
- last_idle_time_ = base::TimeTicks::Now();
- scheduler_->PerformIdleWork();
- }
-
- scheduler_->ProcessPendingQueries();
- }
-
- ScheduleDelayedWork(
- base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodBusyMs));
-}
-
-bool GpuCommandBufferStub::HasUnprocessedCommands() {
- if (command_buffer_) {
- gpu::CommandBuffer::State state = command_buffer_->GetLastState();
- return command_buffer_->GetPutOffset() != state.get_offset &&
- !gpu::error::IsError(state.error);
- }
- return false;
-}
-
-void GpuCommandBufferStub::ScheduleDelayedWork(base::TimeDelta delay) {
- bool has_more_work = scheduler_.get() && (scheduler_->HasPendingQueries() ||
- scheduler_->HasMoreIdleWork());
- if (!has_more_work) {
- last_idle_time_ = base::TimeTicks();
- return;
- }
-
- base::TimeTicks current_time = base::TimeTicks::Now();
- // |process_delayed_work_time_| is set if processing of delayed work is
- // already scheduled. Just update the time if already scheduled.
- if (!process_delayed_work_time_.is_null()) {
- process_delayed_work_time_ = current_time + delay;
- return;
- }
-
- // Idle when no messages are processed between now and when
- // PollWork is called.
- previous_processed_num_ =
- channel()->gpu_channel_manager()->GetProcessedOrderNum();
- if (last_idle_time_.is_null())
- last_idle_time_ = current_time;
-
- // IsScheduled() returns true after passing all unschedule fences
- // and this is when we can start performing idle work. Idle work
- // is done synchronously so we can set delay to 0 and instead poll
- // for more work at the rate idle work is performed. This also ensures
- // that idle work is done as efficiently as possible without any
- // unnecessary delays.
- if (scheduler_.get() && scheduler_->scheduled() &&
- scheduler_->HasMoreIdleWork()) {
- delay = base::TimeDelta();
- }
-
- process_delayed_work_time_ = current_time + delay;
- task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
- delay);
-}
-
-bool GpuCommandBufferStub::MakeCurrent() {
- if (decoder_->MakeCurrent())
- return true;
- DLOG(ERROR) << "Context lost because MakeCurrent failed.";
- command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
- command_buffer_->SetParseError(gpu::error::kLostContext);
- CheckContextLost();
- return false;
-}
-
-void GpuCommandBufferStub::Destroy() {
- if (wait_for_token_) {
- Send(wait_for_token_->reply.release());
- wait_for_token_.reset();
- }
- if (wait_for_get_offset_) {
- Send(wait_for_get_offset_->reply.release());
- wait_for_get_offset_.reset();
- }
-
- if (initialized_) {
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
- if (handle_.is_null() && !active_url_.is_empty()) {
- gpu_channel_manager->Send(
- new GpuHostMsg_DidDestroyOffscreenContext(active_url_));
- }
- }
-
- while (!sync_points_.empty())
- OnRetireSyncPoint(sync_points_.front());
-
- if (decoder_)
- decoder_->set_engine(NULL);
-
- // The scheduler has raw references to the decoder and the command buffer so
- // destroy it before those.
- scheduler_.reset();
-
- sync_point_client_.reset();
-
- bool have_context = false;
- if (decoder_ && decoder_->GetGLContext()) {
- // Try to make the context current regardless of whether it was lost, so we
- // don't leak resources.
- have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get());
- }
- FOR_EACH_OBSERVER(DestructionObserver,
- destruction_observers_,
- OnWillDestroyStub());
-
- if (decoder_) {
- decoder_->Destroy(have_context);
- decoder_.reset();
- }
-
- command_buffer_.reset();
-
- // Remove this after crbug.com/248395 is sorted out.
- surface_ = NULL;
-}
-
-void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
- Destroy();
- GpuCommandBufferMsg_Initialize::WriteReplyParams(
- reply_message, false, gpu::Capabilities());
- Send(reply_message);
-}
-
-void GpuCommandBufferStub::OnInitialize(
- base::SharedMemoryHandle shared_state_handle,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
- DCHECK(!command_buffer_.get());
-
- scoped_ptr<base::SharedMemory> shared_state_shm(
- new base::SharedMemory(shared_state_handle, false));
-
- command_buffer_.reset(new gpu::CommandBufferService(
- context_group_->transfer_buffer_manager()));
-
- bool result = command_buffer_->Initialize();
- DCHECK(result);
-
- GpuChannelManager* manager = channel_->gpu_channel_manager();
- DCHECK(manager);
-
- decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
- scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
- decoder_.get(),
- decoder_.get()));
- sync_point_client_ = sync_point_manager_->CreateSyncPointClient(
- channel_->GetSyncPointOrderData(), gpu::CommandBufferNamespace::GPU_IO,
- command_buffer_id_);
-
- if (preemption_flag_.get())
- scheduler_->SetPreemptByFlag(preemption_flag_);
-
- decoder_->set_engine(scheduler_.get());
-
- if (!handle_.is_null()) {
- surface_ = ImageTransportSurface::CreateSurface(
- channel_->gpu_channel_manager(),
- this,
- handle_);
- } else {
- surface_ = manager->GetDefaultOffscreenSurface();
- }
-
- if (!surface_.get()) {
- DLOG(ERROR) << "Failed to create surface.";
- OnInitializeFailed(reply_message);
- return;
- }
-
- scoped_refptr<gfx::GLContext> context;
- if (use_virtualized_gl_context_ && channel_->share_group()) {
- context = channel_->share_group()->GetSharedContext();
- if (!context.get()) {
- context = gfx::GLContext::CreateGLContext(
- channel_->share_group(),
- channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(),
- gpu_preference_);
- if (!context.get()) {
- DLOG(ERROR) << "Failed to create shared context for virtualization.";
- OnInitializeFailed(reply_message);
- return;
- }
- channel_->share_group()->SetSharedContext(context.get());
- }
- // This should be a non-virtual GL context.
- DCHECK(context->GetHandle());
- context = new gpu::GLContextVirtual(
- channel_->share_group(), context.get(), decoder_->AsWeakPtr());
- if (!context->Initialize(surface_.get(), gpu_preference_)) {
- // TODO(sievers): The real context created above for the default
- // offscreen surface might not be compatible with this surface.
- // Need to adjust at least GLX to be able to create the initial context
- // with a config that is compatible with onscreen and offscreen surfaces.
- context = NULL;
-
- DLOG(ERROR) << "Failed to initialize virtual GL context.";
- OnInitializeFailed(reply_message);
- return;
- }
- }
- if (!context.get()) {
- context = gfx::GLContext::CreateGLContext(
- channel_->share_group(), surface_.get(), gpu_preference_);
- }
- if (!context.get()) {
- DLOG(ERROR) << "Failed to create context.";
- OnInitializeFailed(reply_message);
- return;
- }
-
- if (!context->MakeCurrent(surface_.get())) {
- LOG(ERROR) << "Failed to make context current.";
- OnInitializeFailed(reply_message);
- return;
- }
-
- if (!context->GetGLStateRestorer()) {
- context->SetGLStateRestorer(
- new gpu::GLStateRestorerImpl(decoder_->AsWeakPtr()));
- }
-
- if (!context_group_->has_program_cache() &&
- !context_group_->feature_info()->workarounds().disable_program_cache) {
- context_group_->set_program_cache(
- channel_->gpu_channel_manager()->program_cache());
- }
-
- // Initialize the decoder with either the view or pbuffer GLContext.
- if (!decoder_->Initialize(surface_, context, offscreen_, initial_size_,
- disallowed_features_, requested_attribs_)) {
- DLOG(ERROR) << "Failed to initialize decoder.";
- OnInitializeFailed(reply_message);
- return;
- }
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableGPUServiceLogging)) {
- decoder_->set_log_commands(true);
- }
-
- decoder_->GetLogger()->SetMsgCallback(
- base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
- base::Unretained(this)));
- decoder_->SetShaderCacheCallback(
- base::Bind(&GpuCommandBufferStub::SendCachedShader,
- base::Unretained(this)));
- decoder_->SetWaitSyncPointCallback(
- base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint,
- base::Unretained(this)));
- decoder_->SetFenceSyncReleaseCallback(base::Bind(
- &GpuCommandBufferStub::OnFenceSyncRelease, base::Unretained(this)));
- decoder_->SetWaitFenceSyncCallback(base::Bind(
- &GpuCommandBufferStub::OnWaitFenceSync, base::Unretained(this)));
-
- command_buffer_->SetPutOffsetChangeCallback(
- base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
- command_buffer_->SetGetBufferChangeCallback(
- base::Bind(&gpu::GpuScheduler::SetGetBuffer,
- base::Unretained(scheduler_.get())));
- command_buffer_->SetParseErrorCallback(
- base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
- scheduler_->SetSchedulingChangedCallback(base::Bind(
- &GpuCommandBufferStub::OnSchedulingChanged, base::Unretained(this)));
-
- if (watchdog_) {
- scheduler_->SetCommandProcessedCallback(
- base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
- base::Unretained(this)));
- }
-
- const size_t kSharedStateSize = sizeof(gpu::CommandBufferSharedState);
- if (!shared_state_shm->Map(kSharedStateSize)) {
- DLOG(ERROR) << "Failed to map shared state buffer.";
- OnInitializeFailed(reply_message);
- return;
- }
- command_buffer_->SetSharedStateBuffer(gpu::MakeBackingFromSharedMemory(
- std::move(shared_state_shm), kSharedStateSize));
-
- gpu::Capabilities capabilities = decoder_->GetCapabilities();
- capabilities.future_sync_points = channel_->allow_future_sync_points();
-
- GpuCommandBufferMsg_Initialize::WriteReplyParams(
- reply_message, true, capabilities);
- Send(reply_message);
-
- if (handle_.is_null() && !active_url_.is_empty()) {
- manager->Send(new GpuHostMsg_DidCreateOffscreenContext(
- active_url_));
- }
-
- initialized_ = true;
-}
-
-void GpuCommandBufferStub::OnCreateStreamTexture(uint32_t texture_id,
- int32_t stream_id,
- bool* succeeded) {
-#if defined(OS_ANDROID)
- *succeeded = StreamTexture::Create(this, texture_id, stream_id);
-#else
- *succeeded = false;
-#endif
-}
-
-void GpuCommandBufferStub::SetLatencyInfoCallback(
- const LatencyInfoCallback& callback) {
- latency_info_callback_ = callback;
-}
-
-int32_t GpuCommandBufferStub::GetRequestedAttribute(int attr) const {
- // The command buffer is pairs of enum, value
- // search for the requested attribute, return the value.
- for (std::vector<int32_t>::const_iterator it = requested_attribs_.begin();
- it != requested_attribs_.end(); ++it) {
- if (*it++ == attr) {
- return *it;
- }
- }
- return -1;
-}
-
-void GpuCommandBufferStub::OnSetGetBuffer(int32_t shm_id,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
- if (command_buffer_)
- command_buffer_->SetGetBuffer(shm_id);
- Send(reply_message);
-}
-
-void GpuCommandBufferStub::OnProduceFrontBuffer(const gpu::Mailbox& mailbox) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnProduceFrontBuffer");
- if (!decoder_) {
- LOG(ERROR) << "Can't produce front buffer before initialization.";
- return;
- }
-
- decoder_->ProduceFrontBuffer(mailbox);
-}
-
-void GpuCommandBufferStub::OnParseError() {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
- DCHECK(command_buffer_.get());
- gpu::CommandBuffer::State state = command_buffer_->GetLastState();
- IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
- route_id_, state.context_lost_reason, state.error);
- msg->set_unblock(true);
- Send(msg);
-
- // Tell the browser about this context loss as well, so it can
- // determine whether client APIs like WebGL need to be immediately
- // blocked from automatically running.
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
- gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext(
- handle_.is_null(), state.context_lost_reason, active_url_));
-
- CheckContextLost();
-}
-
-void GpuCommandBufferStub::OnSchedulingChanged(bool scheduled) {
- TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnSchedulingChanged", "scheduled",
- scheduled);
- channel_->OnStubSchedulingChanged(this, scheduled);
-}
-
-void GpuCommandBufferStub::OnWaitForTokenInRange(int32_t start,
- int32_t end,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForTokenInRange");
- DCHECK(command_buffer_.get());
- CheckContextLost();
- if (wait_for_token_)
- LOG(ERROR) << "Got WaitForToken command while currently waiting for token.";
- wait_for_token_ =
- make_scoped_ptr(new WaitForCommandState(start, end, reply_message));
- CheckCompleteWaits();
-}
-
-void GpuCommandBufferStub::OnWaitForGetOffsetInRange(
- int32_t start,
- int32_t end,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForGetOffsetInRange");
- DCHECK(command_buffer_.get());
- CheckContextLost();
- if (wait_for_get_offset_) {
- LOG(ERROR)
- << "Got WaitForGetOffset command while currently waiting for offset.";
- }
- wait_for_get_offset_ =
- make_scoped_ptr(new WaitForCommandState(start, end, reply_message));
- CheckCompleteWaits();
-}
-
-void GpuCommandBufferStub::CheckCompleteWaits() {
- if (wait_for_token_ || wait_for_get_offset_) {
- gpu::CommandBuffer::State state = command_buffer_->GetLastState();
- if (wait_for_token_ &&
- (gpu::CommandBuffer::InRange(
- wait_for_token_->start, wait_for_token_->end, state.token) ||
- state.error != gpu::error::kNoError)) {
- ReportState();
- GpuCommandBufferMsg_WaitForTokenInRange::WriteReplyParams(
- wait_for_token_->reply.get(), state);
- Send(wait_for_token_->reply.release());
- wait_for_token_.reset();
- }
- if (wait_for_get_offset_ &&
- (gpu::CommandBuffer::InRange(wait_for_get_offset_->start,
- wait_for_get_offset_->end,
- state.get_offset) ||
- state.error != gpu::error::kNoError)) {
- ReportState();
- GpuCommandBufferMsg_WaitForGetOffsetInRange::WriteReplyParams(
- wait_for_get_offset_->reply.get(), state);
- Send(wait_for_get_offset_->reply.release());
- wait_for_get_offset_.reset();
- }
- }
-}
-
-void GpuCommandBufferStub::OnAsyncFlush(
- int32_t put_offset,
- uint32_t flush_count,
- const std::vector<ui::LatencyInfo>& latency_info) {
- TRACE_EVENT1(
- "gpu", "GpuCommandBufferStub::OnAsyncFlush", "put_offset", put_offset);
- DCHECK(command_buffer_);
-
- // We received this message out-of-order. This should not happen but is here
- // to catch regressions. Ignore the message.
- DVLOG_IF(0, flush_count - last_flush_count_ >= 0x8000000U)
- << "Received a Flush message out-of-order";
-
- if (flush_count > last_flush_count_ &&
- ui::LatencyInfo::Verify(latency_info,
- "GpuCommandBufferStub::OnAsyncFlush") &&
- !latency_info_callback_.is_null()) {
- latency_info_callback_.Run(latency_info);
- }
-
- last_flush_count_ = flush_count;
- gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
- command_buffer_->Flush(put_offset);
- gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
-
- if (pre_state.get_offset != post_state.get_offset)
- ReportState();
-
-#if defined(OS_ANDROID)
- GpuChannelManager* manager = channel_->gpu_channel_manager();
- manager->DidAccessGpu();
-#endif
-}
-
-void GpuCommandBufferStub::OnRegisterTransferBuffer(
- int32_t id,
- base::SharedMemoryHandle transfer_buffer,
- uint32_t size) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
-
- // Take ownership of the memory and map it into this process.
- // This validates the size.
- scoped_ptr<base::SharedMemory> shared_memory(
- new base::SharedMemory(transfer_buffer, false));
- if (!shared_memory->Map(size)) {
- DVLOG(0) << "Failed to map shared memory.";
- return;
- }
-
- if (command_buffer_) {
- command_buffer_->RegisterTransferBuffer(
- id, gpu::MakeBackingFromSharedMemory(std::move(shared_memory), size));
- }
-}
-
-void GpuCommandBufferStub::OnDestroyTransferBuffer(int32_t id) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
-
- if (command_buffer_)
- command_buffer_->DestroyTransferBuffer(id);
-}
-
-void GpuCommandBufferStub::OnCommandProcessed() {
- if (watchdog_)
- watchdog_->CheckArmed();
-}
-
-void GpuCommandBufferStub::ReportState() { command_buffer_->UpdateState(); }
-
-void GpuCommandBufferStub::PutChanged() {
- FastSetActiveURL(active_url_, active_url_hash_);
- scheduler_->PutChanged();
-}
-
-void GpuCommandBufferStub::OnCreateVideoDecoder(
- const media::VideoDecodeAccelerator::Config& config,
- int32_t decoder_route_id,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
- GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator(
- decoder_route_id, this, channel_->io_task_runner());
- decoder->Initialize(config, reply_message);
- // decoder is registered as a DestructionObserver of this stub and will
- // self-delete during destruction of this stub.
-}
-
-void GpuCommandBufferStub::OnCreateVideoEncoder(
- media::VideoPixelFormat input_format,
- const gfx::Size& input_visible_size,
- media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- int32_t encoder_route_id,
- IPC::Message* reply_message) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoEncoder");
- GpuVideoEncodeAccelerator* encoder =
- new GpuVideoEncodeAccelerator(encoder_route_id, this);
- encoder->Initialize(input_format,
- input_visible_size,
- output_profile,
- initial_bitrate,
- reply_message);
- // encoder is registered as a DestructionObserver of this stub and will
- // self-delete during destruction of this stub.
-}
-
-void GpuCommandBufferStub::InsertSyncPoint(uint32_t sync_point, bool retire) {
- sync_points_.push_back(sync_point);
- if (retire) {
- OnMessageReceived(
- GpuCommandBufferMsg_RetireSyncPoint(route_id_, sync_point));
- }
-}
-
-void GpuCommandBufferStub::OnRetireSyncPoint(uint32_t sync_point) {
- DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
- sync_points_.pop_front();
-
- gpu::gles2::MailboxManager* mailbox_manager =
- context_group_->mailbox_manager();
- if (mailbox_manager->UsesSync() && MakeCurrent()) {
- // Old sync points are global and do not have a command buffer ID,
- // We can simply use the global sync point number as the release count with
- // 0 for the command buffer ID (under normal circumstances 0 is invalid so
- // will not be used) until the old sync points are replaced.
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0, 0,
- sync_point);
- mailbox_manager->PushTextureUpdates(sync_token);
- }
-
- sync_point_manager_->RetireSyncPoint(sync_point);
-}
-
-bool GpuCommandBufferStub::OnWaitSyncPoint(uint32_t sync_point) {
- DCHECK(!waiting_for_sync_point_);
- DCHECK(scheduler_->scheduled());
- if (!sync_point)
- return true;
- if (sync_point_manager_->IsSyncPointRetired(sync_point)) {
- // Old sync points are global and do not have a command buffer ID,
- // We can simply use the global sync point number as the release count with
- // 0 for the command buffer ID (under normal circumstances 0 is invalid so
- // will not be used) until the old sync points are replaced.
- PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point);
- return true;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub",
- this);
-
- waiting_for_sync_point_ = true;
- sync_point_manager_->AddSyncPointCallback(
- sync_point,
- base::Bind(&RunOnThread, task_runner_,
- base::Bind(&GpuCommandBufferStub::OnWaitSyncPointCompleted,
- this->AsWeakPtr(), sync_point)));
-
- if (!waiting_for_sync_point_)
- return true;
-
- scheduler_->SetScheduled(false);
- return false;
-}
-
-void GpuCommandBufferStub::OnWaitSyncPointCompleted(uint32_t sync_point) {
- DCHECK(waiting_for_sync_point_);
- TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub",
- this);
- // Old sync points are global and do not have a command buffer ID,
- // We can simply use the global sync point number as the release count with
- // 0 for the command buffer ID (under normal circumstances 0 is invalid so
- // will not be used) until the old sync points are replaced.
- PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point);
- waiting_for_sync_point_ = false;
- scheduler_->SetScheduled(true);
-}
-
-void GpuCommandBufferStub::PullTextureUpdates(
- gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint32_t release) {
- gpu::gles2::MailboxManager* mailbox_manager =
- context_group_->mailbox_manager();
- if (mailbox_manager->UsesSync() && MakeCurrent()) {
- gpu::SyncToken sync_token(namespace_id, 0, command_buffer_id, release);
- mailbox_manager->PullTextureUpdates(sync_token);
- }
-}
-
-void GpuCommandBufferStub::OnSignalSyncPoint(uint32_t sync_point, uint32_t id) {
- sync_point_manager_->AddSyncPointCallback(
- sync_point,
- base::Bind(&GpuCommandBufferStub::OnSignalAck, this->AsWeakPtr(), id));
-}
-
-void GpuCommandBufferStub::OnSignalSyncToken(const gpu::SyncToken& sync_token,
- uint32_t id) {
- scoped_refptr<gpu::SyncPointClientState> release_state =
- sync_point_manager_->GetSyncPointClientState(
- sync_token.namespace_id(), sync_token.command_buffer_id());
-
- if (release_state) {
- sync_point_client_->Wait(release_state.get(), sync_token.release_count(),
- base::Bind(&GpuCommandBufferStub::OnSignalAck,
- this->AsWeakPtr(), id));
- } else {
- OnSignalAck(id);
- }
-}
-
-void GpuCommandBufferStub::OnSignalAck(uint32_t id) {
- Send(new GpuCommandBufferMsg_SignalAck(route_id_, id));
-}
-
-void GpuCommandBufferStub::OnSignalQuery(uint32_t query_id, uint32_t id) {
- if (decoder_) {
- gpu::gles2::QueryManager* query_manager = decoder_->GetQueryManager();
- if (query_manager) {
- gpu::gles2::QueryManager::Query* query =
- query_manager->GetQuery(query_id);
- if (query) {
- query->AddCallback(
- base::Bind(&GpuCommandBufferStub::OnSignalAck,
- this->AsWeakPtr(),
- id));
- return;
- }
- }
- }
- // Something went wrong, run callback immediately.
- OnSignalAck(id);
-}
-
-void GpuCommandBufferStub::OnFenceSyncRelease(uint64_t release) {
- if (sync_point_client_->client_state()->IsFenceSyncReleased(release)) {
- DLOG(ERROR) << "Fence Sync has already been released.";
- return;
- }
-
- gpu::gles2::MailboxManager* mailbox_manager =
- context_group_->mailbox_manager();
- if (mailbox_manager->UsesSync() && MakeCurrent()) {
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, 0,
- command_buffer_id_, release);
- mailbox_manager->PushTextureUpdates(sync_token);
- }
-
- sync_point_client_->ReleaseFenceSync(release);
-}
-
-bool GpuCommandBufferStub::OnWaitFenceSync(
- gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint64_t release) {
- DCHECK(!waiting_for_sync_point_);
- DCHECK(scheduler_->scheduled());
-
- scoped_refptr<gpu::SyncPointClientState> release_state =
- sync_point_manager_->GetSyncPointClientState(namespace_id,
- command_buffer_id);
-
- if (!release_state)
- return true;
-
- if (release_state->IsFenceSyncReleased(release)) {
- PullTextureUpdates(namespace_id, command_buffer_id, release);
- return true;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub",
- this);
- waiting_for_sync_point_ = true;
- sync_point_client_->WaitNonThreadSafe(
- release_state.get(), release, task_runner_,
- base::Bind(&GpuCommandBufferStub::OnWaitFenceSyncCompleted,
- this->AsWeakPtr(), namespace_id, command_buffer_id, release));
-
- if (!waiting_for_sync_point_)
- return true;
-
- scheduler_->SetScheduled(false);
- return false;
-}
-
-void GpuCommandBufferStub::OnWaitFenceSyncCompleted(
- gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint64_t release) {
- DCHECK(waiting_for_sync_point_);
- TRACE_EVENT_ASYNC_END1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub",
- this);
- PullTextureUpdates(namespace_id, command_buffer_id, release);
- waiting_for_sync_point_ = false;
- scheduler_->SetScheduled(true);
-}
-
-void GpuCommandBufferStub::OnCreateImage(
- const GpuCommandBufferMsg_CreateImage_Params& params) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateImage");
- const int32_t id = params.id;
- const gfx::GpuMemoryBufferHandle& handle = params.gpu_memory_buffer;
- const gfx::Size& size = params.size;
- const gfx::BufferFormat& format = params.format;
- const uint32_t internalformat = params.internal_format;
- const uint64_t image_release_count = params.image_release_count;
-
- if (!decoder_)
- return;
-
- gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
- DCHECK(image_manager);
- if (image_manager->LookupImage(id)) {
- LOG(ERROR) << "Image already exists with same ID.";
- return;
- }
-
- if (!gpu::ImageFactory::IsGpuMemoryBufferFormatSupported(
- format, decoder_->GetCapabilities())) {
- LOG(ERROR) << "Format is not supported.";
- return;
- }
-
- if (!gpu::ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat(size,
- format)) {
- LOG(ERROR) << "Invalid image size for format.";
- return;
- }
-
- if (!gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
- internalformat, format)) {
- LOG(ERROR) << "Incompatible image format.";
- return;
- }
-
- scoped_refptr<gl::GLImage> image = channel()->CreateImageForGpuMemoryBuffer(
- handle, size, format, internalformat);
- if (!image.get())
- return;
-
- image_manager->AddImage(image.get(), id);
- if (image_release_count) {
- sync_point_client_->ReleaseFenceSync(image_release_count);
- }
-}
-
-void GpuCommandBufferStub::OnDestroyImage(int32_t id) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyImage");
-
- if (!decoder_)
- return;
-
- gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
- DCHECK(image_manager);
- if (!image_manager->LookupImage(id)) {
- LOG(ERROR) << "Image with ID doesn't exist.";
- return;
- }
-
- image_manager->RemoveImage(id);
-}
-
-void GpuCommandBufferStub::SendConsoleMessage(int32_t id,
- const std::string& message) {
- GPUCommandBufferConsoleMessage console_message;
- console_message.id = id;
- console_message.message = message;
- IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
- route_id_, console_message);
- msg->set_unblock(true);
- Send(msg);
-}
-
-void GpuCommandBufferStub::SendCachedShader(
- const std::string& key, const std::string& shader) {
- channel_->CacheShader(key, shader);
-}
-
-void GpuCommandBufferStub::AddDestructionObserver(
- DestructionObserver* observer) {
- destruction_observers_.AddObserver(observer);
-}
-
-void GpuCommandBufferStub::RemoveDestructionObserver(
- DestructionObserver* observer) {
- destruction_observers_.RemoveObserver(observer);
-}
-
-const gpu::gles2::FeatureInfo* GpuCommandBufferStub::GetFeatureInfo() const {
- return context_group_->feature_info();
-}
-
-gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const {
- return context_group_->memory_tracker();
-}
-
-bool GpuCommandBufferStub::CheckContextLost() {
- DCHECK(command_buffer_);
- gpu::CommandBuffer::State state = command_buffer_->GetLastState();
- bool was_lost = state.error == gpu::error::kLostContext;
-
- if (was_lost) {
- bool was_lost_by_robustness =
- decoder_ && decoder_->WasContextLostByRobustnessExtension();
-
- // Work around issues with recovery by allowing a new GPU process to launch.
- if ((was_lost_by_robustness ||
- context_group_->feature_info()->workarounds().exit_on_context_lost) &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSingleProcess) &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kInProcessGPU)) {
- LOG(ERROR) << "Exiting GPU process because some drivers cannot recover"
- << " from problems.";
-#if defined(OS_WIN)
- base::win::SetShouldCrashOnProcessDetach(false);
-#endif
- exit(0);
- }
-
- // Lose all other contexts if the reset was triggered by the robustness
- // extension instead of being synthetic.
- if (was_lost_by_robustness &&
- (gfx::GLContext::LosesAllContextsOnContextLost() ||
- use_virtualized_gl_context_)) {
- channel_->LoseAllContexts();
- }
- }
-
- CheckCompleteWaits();
- return was_lost;
-}
-
-void GpuCommandBufferStub::MarkContextLost() {
- if (!command_buffer_ ||
- command_buffer_->GetLastState().error == gpu::error::kLostContext)
- return;
-
- command_buffer_->SetContextLostReason(gpu::error::kUnknown);
- if (decoder_)
- decoder_->MarkContextLost(gpu::error::kUnknown);
- command_buffer_->SetParseError(gpu::error::kLostContext);
-}
-
-void GpuCommandBufferStub::SendSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result) {
- Send(new GpuCommandBufferMsg_SwapBuffersCompleted(route_id_, latency_info,
- result));
-}
-
-void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) {
- Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase,
- interval));
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_command_buffer_stub.h b/chromium/content/common/gpu/gpu_command_buffer_stub.h
deleted file mode 100644
index a9374d7b0ec..00000000000
--- a/chromium/content/common/gpu/gpu_command_buffer_stub.h
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_COMMAND_BUFFER_STUB_H_
-#define CONTENT_COMMON_GPU_GPU_COMMAND_BUFFER_STUB_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_memory_manager.h"
-#include "gpu/command_buffer/common/constants.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "gpu/command_buffer/service/command_buffer_service.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/gpu_scheduler.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_sender.h"
-#include "media/video/video_decode_accelerator.h"
-#include "ui/events/latency_info.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/swap_result.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/gpu_preference.h"
-#include "url/gurl.h"
-
-namespace gpu {
-struct Mailbox;
-struct SyncToken;
-class SyncPointClient;
-class SyncPointManager;
-class ValueStateMap;
-namespace gles2 {
-class MailboxManager;
-class SubscriptionRefSet;
-}
-}
-
-struct GpuCommandBufferMsg_CreateImage_Params;
-
-namespace content {
-
-class GpuChannel;
-class GpuVideoDecodeAccelerator;
-class GpuVideoEncodeAccelerator;
-class GpuWatchdog;
-struct WaitForCommandState;
-
-class GpuCommandBufferStub
- : public IPC::Listener,
- public IPC::Sender,
- public base::SupportsWeakPtr<GpuCommandBufferStub> {
- public:
- class DestructionObserver {
- public:
- // Called in Destroy(), before the context/surface are released.
- virtual void OnWillDestroyStub() = 0;
-
- protected:
- virtual ~DestructionObserver() {}
- };
-
- typedef base::Callback<void(const std::vector<ui::LatencyInfo>&)>
- LatencyInfoCallback;
-
- GpuCommandBufferStub(
- GpuChannel* channel,
- gpu::SyncPointManager* sync_point_manager,
- base::SingleThreadTaskRunner* task_runner,
- GpuCommandBufferStub* share_group,
- const gfx::GLSurfaceHandle& handle,
- gpu::gles2::MailboxManager* mailbox_manager,
- gpu::PreemptionFlag* preempt_by_flag,
- gpu::gles2::SubscriptionRefSet* subscription_ref_set,
- gpu::ValueStateMap* pending_valuebuffer_state,
- const gfx::Size& size,
- const gpu::gles2::DisallowedFeatures& disallowed_features,
- const std::vector<int32_t>& attribs,
- gfx::GpuPreference gpu_preference,
- int32_t stream_id,
- int32_t route_id,
- bool offscreen,
- GpuWatchdog* watchdog,
- const GURL& active_url);
-
- ~GpuCommandBufferStub() override;
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& message) override;
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* msg) override;
-
- gpu::gles2::MemoryTracker* GetMemoryTracker() const;
-
- // Whether this command buffer can currently handle IPC messages.
- bool IsScheduled();
-
- // Whether there are commands in the buffer that haven't been processed.
- bool HasUnprocessedCommands();
-
- gpu::gles2::GLES2Decoder* decoder() const { return decoder_.get(); }
- gpu::GpuScheduler* scheduler() const { return scheduler_.get(); }
- GpuChannel* channel() const { return channel_; }
-
- // Unique command buffer ID for this command buffer stub.
- uint64_t command_buffer_id() const { return command_buffer_id_; }
-
- // Identifies the various GpuCommandBufferStubs in the GPU process belonging
- // to the same renderer process.
- int32_t route_id() const { return route_id_; }
-
- // Identifies the stream for this command buffer.
- int32_t stream_id() const { return stream_id_; }
-
- gfx::GpuPreference gpu_preference() { return gpu_preference_; }
-
- int32_t GetRequestedAttribute(int attr) const;
-
- // Sends a message to the console.
- void SendConsoleMessage(int32_t id, const std::string& message);
-
- void SendCachedShader(const std::string& key, const std::string& shader);
-
- gfx::GLSurface* surface() const { return surface_.get(); }
-
- void AddDestructionObserver(DestructionObserver* observer);
- void RemoveDestructionObserver(DestructionObserver* observer);
-
- // Associates a sync point to this stub. When the stub is destroyed, it will
- // retire all sync points that haven't been previously retired.
- void InsertSyncPoint(uint32_t sync_point, bool retire);
-
- void SetLatencyInfoCallback(const LatencyInfoCallback& callback);
-
- void MarkContextLost();
-
- const gpu::gles2::FeatureInfo* GetFeatureInfo() const;
-
- void SendSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result);
- void SendUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
-
- private:
- GpuMemoryManager* GetMemoryManager() const;
-
- void Destroy();
-
- bool MakeCurrent();
-
- // Cleans up and sends reply if OnInitialize failed.
- void OnInitializeFailed(IPC::Message* reply_message);
-
- // Message handlers:
- void OnInitialize(base::SharedMemoryHandle shared_state_shm,
- IPC::Message* reply_message);
- void OnSetGetBuffer(int32_t shm_id, IPC::Message* reply_message);
- void OnProduceFrontBuffer(const gpu::Mailbox& mailbox);
- void OnGetState(IPC::Message* reply_message);
- void OnWaitForTokenInRange(int32_t start,
- int32_t end,
- IPC::Message* reply_message);
- void OnWaitForGetOffsetInRange(int32_t start,
- int32_t end,
- IPC::Message* reply_message);
- void OnAsyncFlush(int32_t put_offset,
- uint32_t flush_count,
- const std::vector<ui::LatencyInfo>& latency_info);
- void OnRegisterTransferBuffer(int32_t id,
- base::SharedMemoryHandle transfer_buffer,
- uint32_t size);
- void OnDestroyTransferBuffer(int32_t id);
- void OnGetTransferBuffer(int32_t id, IPC::Message* reply_message);
-
- void OnCreateVideoDecoder(const media::VideoDecodeAccelerator::Config& config,
- int32_t route_id,
- IPC::Message* reply_message);
- void OnCreateVideoEncoder(media::VideoPixelFormat input_format,
- const gfx::Size& input_visible_size,
- media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- int32_t route_id,
- IPC::Message* reply_message);
-
- void OnEnsureBackbuffer();
-
- void OnRetireSyncPoint(uint32_t sync_point);
- bool OnWaitSyncPoint(uint32_t sync_point);
- void OnWaitSyncPointCompleted(uint32_t sync_point);
- void OnSignalSyncPoint(uint32_t sync_point, uint32_t id);
- void OnSignalSyncToken(const gpu::SyncToken& sync_token, uint32_t id);
- void OnSignalAck(uint32_t id);
- void OnSignalQuery(uint32_t query, uint32_t id);
-
- void OnFenceSyncRelease(uint64_t release);
- bool OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint64_t release);
- void OnWaitFenceSyncCompleted(gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint64_t release);
-
- void OnCreateImage(const GpuCommandBufferMsg_CreateImage_Params& params);
- void OnDestroyImage(int32_t id);
- void OnCreateStreamTexture(uint32_t texture_id,
- int32_t stream_id,
- bool* succeeded);
-
- void OnCommandProcessed();
- void OnParseError();
- void OnSchedulingChanged(bool scheduled);
-
- void ReportState();
-
- // Wrapper for GpuScheduler::PutChanged that sets the crash report URL.
- void PutChanged();
-
- // Poll the command buffer to execute work.
- void PollWork();
- void PerformWork();
-
- // Schedule processing of delayed work. This updates the time at which
- // delayed work should be processed. |process_delayed_work_time_| is
- // updated to current time + delay. Call this after processing some amount
- // of delayed work.
- void ScheduleDelayedWork(base::TimeDelta delay);
-
- bool CheckContextLost();
- void CheckCompleteWaits();
- void PullTextureUpdates(gpu::CommandBufferNamespace namespace_id,
- uint64_t command_buffer_id,
- uint32_t release);
-
- // The lifetime of objects of this class is managed by a GpuChannel. The
- // GpuChannels destroy all the GpuCommandBufferStubs that they own when they
- // are destroyed. So a raw pointer is safe.
- GpuChannel* channel_;
-
- // Outlives the stub.
- gpu::SyncPointManager* sync_point_manager_;
-
- // Task runner for main thread.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
- // The group of contexts that share namespaces with this context.
- scoped_refptr<gpu::gles2::ContextGroup> context_group_;
-
- bool initialized_;
- gfx::GLSurfaceHandle handle_;
- gfx::Size initial_size_;
- gpu::gles2::DisallowedFeatures disallowed_features_;
- std::vector<int32_t> requested_attribs_;
- gfx::GpuPreference gpu_preference_;
- bool use_virtualized_gl_context_;
- const uint64_t command_buffer_id_;
- const int32_t stream_id_;
- const int32_t route_id_;
- const bool offscreen_;
- uint32_t last_flush_count_;
-
- scoped_ptr<gpu::CommandBufferService> command_buffer_;
- scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
- scoped_ptr<gpu::GpuScheduler> scheduler_;
- scoped_ptr<gpu::SyncPointClient> sync_point_client_;
- scoped_refptr<gfx::GLSurface> surface_;
-
- GpuWatchdog* watchdog_;
-
- base::ObserverList<DestructionObserver> destruction_observers_;
-
- // A queue of sync points associated with this stub.
- std::deque<uint32_t> sync_points_;
- bool waiting_for_sync_point_;
-
- base::TimeTicks process_delayed_work_time_;
- uint32_t previous_processed_num_;
- base::TimeTicks last_idle_time_;
-
- scoped_refptr<gpu::PreemptionFlag> preemption_flag_;
-
- LatencyInfoCallback latency_info_callback_;
-
- GURL active_url_;
- size_t active_url_hash_;
-
- scoped_ptr<WaitForCommandState> wait_for_token_;
- scoped_ptr<WaitForCommandState> wait_for_get_offset_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_COMMAND_BUFFER_STUB_H_
diff --git a/chromium/content/common/gpu/gpu_config.h b/chromium/content/common/gpu/gpu_config.h
deleted file mode 100644
index 74d5ee05b86..00000000000
--- a/chromium/content/common/gpu/gpu_config.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_CONFIG_H_
-#define CONTENT_COMMON_GPU_GPU_CONFIG_H_
-
-// This file declares common preprocessor configuration for the GPU process.
-
-#include "build/build_config.h"
-
-#endif // CONTENT_COMMON_GPU_GPU_CONFIG_H_
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory.cc
deleted file mode 100644
index 8469e162178..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/gpu_memory_buffer_factory.h"
-
-#include "base/logging.h"
-#include "build/build_config.h"
-
-#if defined(OS_MACOSX)
-#include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
-#endif
-
-#if defined(OS_ANDROID)
-#include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
-#endif
-
-#if defined(USE_OZONE)
-#include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
-#endif
-
-namespace content {
-
-// static
-gfx::GpuMemoryBufferType GpuMemoryBufferFactory::GetNativeType() {
-#if defined(OS_MACOSX)
- return gfx::IO_SURFACE_BUFFER;
-#endif
-#if defined(OS_ANDROID)
- return gfx::SURFACE_TEXTURE_BUFFER;
-#endif
-#if defined(USE_OZONE)
- return gfx::OZONE_NATIVE_PIXMAP;
-#endif
- return gfx::EMPTY_BUFFER;
-}
-
-// static
-scoped_ptr<GpuMemoryBufferFactory> GpuMemoryBufferFactory::CreateNativeType() {
-#if defined(OS_MACOSX)
- return make_scoped_ptr(new GpuMemoryBufferFactoryIOSurface);
-#endif
-#if defined(OS_ANDROID)
- return make_scoped_ptr(new GpuMemoryBufferFactorySurfaceTexture);
-#endif
-#if defined(USE_OZONE)
- return make_scoped_ptr(new GpuMemoryBufferFactoryOzoneNativePixmap);
-#endif
- NOTREACHED();
- return nullptr;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory.h b/chromium/content/common/gpu/gpu_memory_buffer_factory.h
deleted file mode 100644
index 77a50f2775c..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace gpu {
-class ImageFactory;
-}
-
-namespace content {
-
-class CONTENT_EXPORT GpuMemoryBufferFactory {
- public:
- virtual ~GpuMemoryBufferFactory() {}
-
- // Returns the native GPU memory buffer factory type. Returns EMPTY_BUFFER
- // type if native buffers are not supported.
- static gfx::GpuMemoryBufferType GetNativeType();
-
- // Creates a new factory instance for native GPU memory buffers.
- static scoped_ptr<GpuMemoryBufferFactory> CreateNativeType();
-
- // Creates a new GPU memory buffer instance. A valid handle is returned on
- // success. It can be called on any thread.
- virtual gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) = 0;
-
- // Creates a new GPU memory buffer instance from an existing handle. A valid
- // handle is returned on success. It can be called on any thread.
- virtual gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) = 0;
-
- // Destroys GPU memory buffer identified by |id|.
- // It can be called on any thread.
- virtual void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id) = 0;
-
- // Type-checking downcast routine.
- virtual gpu::ImageFactory* AsImageFactory() = 0;
-
- protected:
- GpuMemoryBufferFactory() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactory);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_H_
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
deleted file mode 100644
index 49fab37b596..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gfx/mac/io_surface.h"
-#include "ui/gl/gl_image_io_surface.h"
-
-namespace content {
-
-GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() {
-}
-
-GpuMemoryBufferFactoryIOSurface::~GpuMemoryBufferFactoryIOSurface() {
-}
-
-// static
-bool GpuMemoryBufferFactoryIOSurface::IsGpuMemoryBufferConfigurationSupported(
- gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- switch (usage) {
- case gfx::BufferUsage::GPU_READ:
- case gfx::BufferUsage::SCANOUT:
- return format == gfx::BufferFormat::BGRA_8888 ||
- format == gfx::BufferFormat::RGBA_8888;
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
- return format == gfx::BufferFormat::R_8 ||
- format == gfx::BufferFormat::BGRA_8888 ||
- format == gfx::BufferFormat::UYVY_422 ||
- format == gfx::BufferFormat::YUV_420_BIPLANAR;
- }
- NOTREACHED();
- return false;
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) {
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
- gfx::CreateIOSurface(size, format));
- if (!io_surface)
- return gfx::GpuMemoryBufferHandle();
-
- {
- base::AutoLock lock(io_surfaces_lock_);
-
- IOSurfaceMapKey key(id, client_id);
- DCHECK(io_surfaces_.find(key) == io_surfaces_.end());
- io_surfaces_[key] = io_surface;
- }
-
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::IO_SURFACE_BUFFER;
- handle.id = id;
- handle.mach_port.reset(IOSurfaceCreateMachPort(io_surface));
- return handle;
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) {
- NOTIMPLEMENTED();
- return gfx::GpuMemoryBufferHandle();
-}
-
-void GpuMemoryBufferFactoryIOSurface::DestroyGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- int client_id) {
- {
- base::AutoLock lock(io_surfaces_lock_);
-
- IOSurfaceMapKey key(id, client_id);
- DCHECK(io_surfaces_.find(key) != io_surfaces_.end());
- io_surfaces_.erase(key);
- }
-}
-
-gpu::ImageFactory* GpuMemoryBufferFactoryIOSurface::AsImageFactory() {
- return this;
-}
-
-scoped_refptr<gl::GLImage>
-GpuMemoryBufferFactoryIOSurface::CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) {
- base::AutoLock lock(io_surfaces_lock_);
-
- DCHECK_EQ(handle.type, gfx::IO_SURFACE_BUFFER);
- IOSurfaceMapKey key(handle.id, client_id);
- IOSurfaceMap::iterator it = io_surfaces_.find(key);
- if (it == io_surfaces_.end())
- return scoped_refptr<gl::GLImage>();
-
- scoped_refptr<gl::GLImageIOSurface> image(
- new gl::GLImageIOSurface(size, internalformat));
- if (!image->Initialize(it->second.get(), handle.id, format))
- return scoped_refptr<gl::GLImage>();
-
- return image;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.h b/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.h
deleted file mode 100644
index d2fd00dbe3d..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_IO_SURFACE_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_IO_SURFACE_H_
-
-#include <utility>
-
-#include <IOSurface/IOSurface.h>
-
-#include "base/containers/hash_tables.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/mac/io_surface.h"
-
-namespace gl {
-class GLImage;
-}
-
-namespace content {
-
-class CONTENT_EXPORT GpuMemoryBufferFactoryIOSurface
- : public GpuMemoryBufferFactory,
- public gpu::ImageFactory {
- public:
- GpuMemoryBufferFactoryIOSurface();
- ~GpuMemoryBufferFactoryIOSurface() override;
-
- static bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- // Overridden from GpuMemoryBufferFactory:
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) override;
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id) override;
- gpu::ImageFactory* AsImageFactory() override;
-
- // Overridden from gpu::ImageFactory:
- scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) override;
-
- private:
- typedef std::pair<gfx::IOSurfaceId, int> IOSurfaceMapKey;
- typedef base::hash_map<IOSurfaceMapKey, base::ScopedCFTypeRef<IOSurfaceRef>>
- IOSurfaceMap;
- // TOOD(reveman): Remove |io_surfaces_| and allow IOSurface backed GMBs to be
- // used with any GPU process by passing a mach_port to CreateImageCHROMIUM.
- IOSurfaceMap io_surfaces_;
- base::Lock io_surfaces_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactoryIOSurface);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_IO_SURFACE_H_
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
deleted file mode 100644
index 7f4a13257f4..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryIOSurface,
- GpuMemoryBufferFactoryTest,
- GpuMemoryBufferFactoryIOSurface);
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc
deleted file mode 100644
index 69fdd3085cb..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
-
-#include "ui/gl/gl_image_ozone_native_pixmap.h"
-#include "ui/ozone/public/client_native_pixmap.h"
-#include "ui/ozone/public/client_native_pixmap_factory.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
-
-namespace content {
-
-GpuMemoryBufferFactoryOzoneNativePixmap::
- GpuMemoryBufferFactoryOzoneNativePixmap() {}
-
-GpuMemoryBufferFactoryOzoneNativePixmap::
- ~GpuMemoryBufferFactoryOzoneNativePixmap() {}
-
-// static
-bool GpuMemoryBufferFactoryOzoneNativePixmap::
- IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- if (!ui::ClientNativePixmapFactory::GetInstance()) {
- // unittests don't have to set ClientNativePixmapFactory.
- return false;
- }
- return ui::ClientNativePixmapFactory::GetInstance()->IsConfigurationSupported(
- format, usage);
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactoryOzoneNativePixmap::CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) {
- scoped_refptr<ui::NativePixmap> pixmap =
- ui::OzonePlatform::GetInstance()
- ->GetSurfaceFactoryOzone()
- ->CreateNativePixmap(surface_handle, size, format, usage);
- if (!pixmap.get()) {
- DLOG(ERROR) << "Failed to create pixmap " << size.width() << "x"
- << size.height() << " format " << static_cast<int>(format)
- << ", usage " << static_cast<int>(usage);
- return gfx::GpuMemoryBufferHandle();
- }
-
- gfx::GpuMemoryBufferHandle new_handle;
- new_handle.type = gfx::OZONE_NATIVE_PIXMAP;
- new_handle.id = id;
- new_handle.native_pixmap_handle = pixmap->ExportHandle();
-
- {
- base::AutoLock lock(native_pixmaps_lock_);
- NativePixmapMapKey key(id.id, client_id);
- DCHECK(native_pixmaps_.find(key) == native_pixmaps_.end());
- native_pixmaps_[key] = pixmap;
- }
-
- return new_handle;
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactoryOzoneNativePixmap::CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) {
- scoped_refptr<ui::NativePixmap> pixmap =
- ui::OzonePlatform::GetInstance()
- ->GetSurfaceFactoryOzone()
- ->CreateNativePixmapFromHandle(handle.native_pixmap_handle);
- if (!pixmap.get()) {
- DLOG(ERROR) << "Failed to create pixmap from handle";
- return gfx::GpuMemoryBufferHandle();
- }
-
- gfx::GpuMemoryBufferHandle new_handle;
- new_handle.type = gfx::OZONE_NATIVE_PIXMAP;
- new_handle.id = id;
- new_handle.native_pixmap_handle = pixmap->ExportHandle();
-
- {
- base::AutoLock lock(native_pixmaps_lock_);
- NativePixmapMapKey key(id.id, client_id);
- DCHECK(native_pixmaps_.find(key) == native_pixmaps_.end());
- native_pixmaps_[key] = pixmap;
- }
-
- return new_handle;
-}
-
-void GpuMemoryBufferFactoryOzoneNativePixmap::DestroyGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- int client_id) {
- base::AutoLock lock(native_pixmaps_lock_);
- auto it = native_pixmaps_.find(NativePixmapMapKey(id.id, client_id));
- DCHECK(it != native_pixmaps_.end());
- native_pixmaps_.erase(it);
-}
-
-gpu::ImageFactory* GpuMemoryBufferFactoryOzoneNativePixmap::AsImageFactory() {
- return this;
-}
-
-scoped_refptr<gl::GLImage>
-GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) {
- DCHECK_EQ(handle.type, gfx::OZONE_NATIVE_PIXMAP);
- scoped_refptr<ui::NativePixmap> pixmap;
- {
- base::AutoLock lock(native_pixmaps_lock_);
- NativePixmapMap::iterator it =
- native_pixmaps_.find(NativePixmapMapKey(handle.id.id, client_id));
- if (it == native_pixmaps_.end()) {
- return nullptr;
- }
- pixmap = it->second;
- }
-
- scoped_refptr<gfx::GLImageOzoneNativePixmap> image(
- new gfx::GLImageOzoneNativePixmap(size, internalformat));
- if (!image->Initialize(pixmap.get(), format)) {
- LOG(ERROR) << "Failed to create GLImage";
- return nullptr;
- }
- return image;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h b/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h
deleted file mode 100644
index f9ea0d25b80..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_PIXMAP_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_PIXMAP_H_
-
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "ui/ozone/public/native_pixmap.h"
-
-namespace gl {
-class GLImage;
-}
-
-namespace content {
-
-class CONTENT_EXPORT GpuMemoryBufferFactoryOzoneNativePixmap
- : public GpuMemoryBufferFactory,
- public gpu::ImageFactory {
- public:
- GpuMemoryBufferFactoryOzoneNativePixmap();
- ~GpuMemoryBufferFactoryOzoneNativePixmap() override;
-
- static bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- // Overridden from GpuMemoryBufferFactory:
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) override;
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id) override;
- gpu::ImageFactory* AsImageFactory() override;
-
- // Overridden from gpu::ImageFactory:
- scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) override;
-
- private:
- using NativePixmapMapKey = std::pair<int, int>;
- using NativePixmapMap =
- base::hash_map<NativePixmapMapKey, scoped_refptr<ui::NativePixmap>>;
- NativePixmapMap native_pixmaps_;
- base::Lock native_pixmaps_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactoryOzoneNativePixmap);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_OZONE_NATIVE_PIXMAP_H_
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
deleted file mode 100644
index bdb974702d9..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryOzoneNativePixmap,
- GpuMemoryBufferFactoryTest,
- GpuMemoryBufferFactoryOzoneNativePixmap);
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryOzoneNativePixmap,
- GpuMemoryBufferFactoryImportTest,
- GpuMemoryBufferFactoryOzoneNativePixmap);
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
deleted file mode 100644
index a4cf15ed30e..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
-
-#include "content/common/android/surface_texture_manager.h"
-#include "ui/gl/android/surface_texture.h"
-#include "ui/gl/gl_image_surface_texture.h"
-
-namespace content {
-
-GpuMemoryBufferFactorySurfaceTexture::GpuMemoryBufferFactorySurfaceTexture() {
-}
-
-GpuMemoryBufferFactorySurfaceTexture::~GpuMemoryBufferFactorySurfaceTexture() {
-}
-
-// static
-bool GpuMemoryBufferFactorySurfaceTexture::
- IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage) {
- switch (usage) {
- case gfx::BufferUsage::GPU_READ:
- case gfx::BufferUsage::SCANOUT:
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
- return false;
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- return format == gfx::BufferFormat::RGBA_8888;
- }
- NOTREACHED();
- return false;
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactorySurfaceTexture::CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) {
- // Note: this needs to be 0 as the surface texture implemenation will take
- // ownership of the texture and call glDeleteTextures when the GPU service
- // attaches the surface texture to a real texture id. glDeleteTextures
- // silently ignores 0.
- const int kDummyTextureId = 0;
- scoped_refptr<gfx::SurfaceTexture> surface_texture =
- gfx::SurfaceTexture::Create(kDummyTextureId);
- if (!surface_texture.get())
- return gfx::GpuMemoryBufferHandle();
-
- SurfaceTextureManager::GetInstance()->RegisterSurfaceTexture(
- id.id, client_id, surface_texture.get());
-
- {
- base::AutoLock lock(surface_textures_lock_);
-
- SurfaceTextureMapKey key(id.id, client_id);
- DCHECK(surface_textures_.find(key) == surface_textures_.end());
- surface_textures_[key] = surface_texture;
- }
-
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SURFACE_TEXTURE_BUFFER;
- handle.id = id;
- return handle;
-}
-
-gfx::GpuMemoryBufferHandle
-GpuMemoryBufferFactorySurfaceTexture::CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) {
- NOTIMPLEMENTED();
- return gfx::GpuMemoryBufferHandle();
-}
-
-void GpuMemoryBufferFactorySurfaceTexture::DestroyGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- int client_id) {
- {
- base::AutoLock lock(surface_textures_lock_);
-
- SurfaceTextureMapKey key(id.id, client_id);
- DCHECK(surface_textures_.find(key) != surface_textures_.end());
- surface_textures_.erase(key);
- }
-
- SurfaceTextureManager::GetInstance()->UnregisterSurfaceTexture(id.id,
- client_id);
-}
-
-gpu::ImageFactory* GpuMemoryBufferFactorySurfaceTexture::AsImageFactory() {
- return this;
-}
-
-scoped_refptr<gl::GLImage>
-GpuMemoryBufferFactorySurfaceTexture::CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) {
- base::AutoLock lock(surface_textures_lock_);
-
- DCHECK_EQ(handle.type, gfx::SURFACE_TEXTURE_BUFFER);
-
- SurfaceTextureMapKey key(handle.id.id, client_id);
- SurfaceTextureMap::iterator it = surface_textures_.find(key);
- if (it == surface_textures_.end())
- return scoped_refptr<gl::GLImage>();
-
- scoped_refptr<gl::GLImageSurfaceTexture> image(
- new gl::GLImageSurfaceTexture(size));
- if (!image->Initialize(it->second.get()))
- return scoped_refptr<gl::GLImage>();
-
- return image;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h b/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h
deleted file mode 100644
index b9eda55dcbd..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SURFACE_TEXTURE_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SURFACE_TEXTURE_H_
-
-#include <utility>
-
-#include "base/containers/hash_tables.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/gpu_memory_buffer_factory.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace gfx {
-class SurfaceTexture;
-}
-
-namespace gl {
-class GLImage;
-}
-
-namespace content {
-
-class CONTENT_EXPORT GpuMemoryBufferFactorySurfaceTexture
- : public GpuMemoryBufferFactory,
- public gpu::ImageFactory {
- public:
- GpuMemoryBufferFactorySurfaceTexture();
- ~GpuMemoryBufferFactorySurfaceTexture() override;
-
- static bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format,
- gfx::BufferUsage usage);
-
- // Overridden from GpuMemoryBufferFactory:
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gfx::PluginWindowHandle surface_handle) override;
- gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferFromHandle(
- const gfx::GpuMemoryBufferHandle& handle,
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- int client_id) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id) override;
- gpu::ImageFactory* AsImageFactory() override;
-
- // Overridden from gpu::ImageFactory:
- scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer(
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- unsigned internalformat,
- int client_id) override;
-
- private:
- typedef std::pair<int, int> SurfaceTextureMapKey;
- typedef base::hash_map<SurfaceTextureMapKey,
- scoped_refptr<gfx::SurfaceTexture>> SurfaceTextureMap;
- SurfaceTextureMap surface_textures_;
- base::Lock surface_textures_lock_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SURFACE_TEXTURE_H_
diff --git a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc b/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
deleted file mode 100644
index 683860fee17..00000000000
--- a/chromium/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
-
-namespace content {
-namespace {
-
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactorySurfaceTexture,
- GpuMemoryBufferFactoryTest,
- GpuMemoryBufferFactorySurfaceTexture);
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_manager.cc b/chromium/content/common/gpu/gpu_memory_manager.cc
deleted file mode 100644
index 4b9eb7c2888..00000000000
--- a/chromium/content/common/gpu/gpu_memory_manager.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_memory_manager.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/message_loop/message_loop.h"
-#include "base/process/process_handle.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_memory_tracking.h"
-#include "content/common/gpu/gpu_memory_uma_stats.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
-
-using gpu::MemoryAllocation;
-
-namespace content {
-namespace {
-
-const uint64_t kBytesAllocatedStep = 16 * 1024 * 1024;
-
-void TrackValueChanged(uint64_t old_size,
- uint64_t new_size,
- uint64_t* total_size) {
- DCHECK(new_size > old_size || *total_size >= (old_size - new_size));
- *total_size += (new_size - old_size);
-}
-
-}
-
-GpuMemoryManager::GpuMemoryManager(GpuChannelManager* channel_manager)
- : channel_manager_(channel_manager),
- bytes_allocated_current_(0),
- bytes_allocated_historical_max_(0) {}
-
-GpuMemoryManager::~GpuMemoryManager() {
- DCHECK(tracking_groups_.empty());
- DCHECK(!bytes_allocated_current_);
-}
-
-void GpuMemoryManager::TrackMemoryAllocatedChange(
- GpuMemoryTrackingGroup* tracking_group,
- uint64_t old_size,
- uint64_t new_size) {
- TrackValueChanged(old_size, new_size, &tracking_group->size_);
- TrackValueChanged(old_size, new_size, &bytes_allocated_current_);
-
- if (GetCurrentUsage() > bytes_allocated_historical_max_ +
- kBytesAllocatedStep) {
- bytes_allocated_historical_max_ = GetCurrentUsage();
- // If we're blowing into new memory usage territory, spam the browser
- // process with the most up-to-date information about our memory usage.
- SendUmaStatsToBrowser();
- }
-}
-
-bool GpuMemoryManager::EnsureGPUMemoryAvailable(uint64_t /* size_needed */) {
- // TODO: Check if there is enough space. Lose contexts until there is.
- return true;
-}
-
-uint64_t GpuMemoryManager::GetTrackerMemoryUsage(
- gpu::gles2::MemoryTracker* tracker) const {
- TrackingGroupMap::const_iterator tracking_group_it =
- tracking_groups_.find(tracker);
- DCHECK(tracking_group_it != tracking_groups_.end());
- return tracking_group_it->second->GetSize();
-}
-
-GpuMemoryTrackingGroup* GpuMemoryManager::CreateTrackingGroup(
- base::ProcessId pid, gpu::gles2::MemoryTracker* memory_tracker) {
- GpuMemoryTrackingGroup* tracking_group = new GpuMemoryTrackingGroup(
- pid, memory_tracker, this);
- DCHECK(!tracking_groups_.count(tracking_group->GetMemoryTracker()));
- tracking_groups_.insert(std::make_pair(tracking_group->GetMemoryTracker(),
- tracking_group));
- return tracking_group;
-}
-
-void GpuMemoryManager::OnDestroyTrackingGroup(
- GpuMemoryTrackingGroup* tracking_group) {
- DCHECK(tracking_groups_.count(tracking_group->GetMemoryTracker()));
- tracking_groups_.erase(tracking_group->GetMemoryTracker());
-}
-
-void GpuMemoryManager::GetVideoMemoryUsageStats(
- GPUVideoMemoryUsageStats* video_memory_usage_stats) const {
- // For each context group, assign its memory usage to its PID
- video_memory_usage_stats->process_map.clear();
- for (TrackingGroupMap::const_iterator i =
- tracking_groups_.begin(); i != tracking_groups_.end(); ++i) {
- const GpuMemoryTrackingGroup* tracking_group = i->second;
- video_memory_usage_stats->process_map[
- tracking_group->GetPid()].video_memory += tracking_group->GetSize();
- }
-
- // Assign the total across all processes in the GPU process
- video_memory_usage_stats->process_map[
- base::GetCurrentProcId()].video_memory = GetCurrentUsage();
- video_memory_usage_stats->process_map[
- base::GetCurrentProcId()].has_duplicates = true;
-
- video_memory_usage_stats->bytes_allocated = GetCurrentUsage();
- video_memory_usage_stats->bytes_allocated_historical_max =
- bytes_allocated_historical_max_;
-}
-
-void GpuMemoryManager::SendUmaStatsToBrowser() {
- if (!channel_manager_)
- return;
- GPUMemoryUmaStats params;
- params.bytes_allocated_current = GetCurrentUsage();
- params.bytes_allocated_max = bytes_allocated_historical_max_;
- params.context_group_count = tracking_groups_.size();
- channel_manager_->Send(new GpuHostMsg_GpuMemoryUmaStats(params));
-}
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_manager.h b/chromium/content/common/gpu/gpu_memory_manager.h
deleted file mode 100644
index 7de22e5aa78..00000000000
--- a/chromium/content/common/gpu/gpu_memory_manager.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_
-
-#include <stdint.h>
-
-#include <list>
-#include <map>
-
-#include "base/cancelable_callback.h"
-#include "base/containers/hash_tables.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "content/public/common/gpu_memory_stats.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-
-namespace content {
-
-class GpuChannelManager;
-class GpuMemoryTrackingGroup;
-
-class CONTENT_EXPORT GpuMemoryManager :
- public base::SupportsWeakPtr<GpuMemoryManager> {
- public:
- explicit GpuMemoryManager(GpuChannelManager* channel_manager);
- ~GpuMemoryManager();
-
- // Retrieve GPU Resource consumption statistics for the task manager
- void GetVideoMemoryUsageStats(
- content::GPUVideoMemoryUsageStats* video_memory_usage_stats) const;
-
- GpuMemoryTrackingGroup* CreateTrackingGroup(
- base::ProcessId pid, gpu::gles2::MemoryTracker* memory_tracker);
-
- uint64_t GetTrackerMemoryUsage(gpu::gles2::MemoryTracker* tracker) const;
-
- private:
- friend class GpuMemoryManagerTest;
- friend class GpuMemoryTrackingGroup;
- friend class GpuMemoryManagerClientState;
-
- typedef std::map<gpu::gles2::MemoryTracker*, GpuMemoryTrackingGroup*>
- TrackingGroupMap;
-
- // Send memory usage stats to the browser process.
- void SendUmaStatsToBrowser();
-
- // Get the current number of bytes allocated.
- uint64_t GetCurrentUsage() const { return bytes_allocated_current_; }
-
- // GpuMemoryTrackingGroup interface
- void TrackMemoryAllocatedChange(GpuMemoryTrackingGroup* tracking_group,
- uint64_t old_size,
- uint64_t new_size);
- void OnDestroyTrackingGroup(GpuMemoryTrackingGroup* tracking_group);
- bool EnsureGPUMemoryAvailable(uint64_t size_needed);
-
- GpuChannelManager* channel_manager_;
-
- // All context groups' tracking structures
- TrackingGroupMap tracking_groups_;
-
- // The current total memory usage, and historical maximum memory usage
- uint64_t bytes_allocated_current_;
- uint64_t bytes_allocated_historical_max_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuMemoryManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_
diff --git a/chromium/content/common/gpu/gpu_memory_tracking.cc b/chromium/content/common/gpu/gpu_memory_tracking.cc
deleted file mode 100644
index 6fa447b5b87..00000000000
--- a/chromium/content/common/gpu/gpu_memory_tracking.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_memory_tracking.h"
-
-#include "content/common/gpu/gpu_memory_manager.h"
-
-namespace content {
-
-GpuMemoryTrackingGroup::GpuMemoryTrackingGroup(
- base::ProcessId pid,
- gpu::gles2::MemoryTracker* memory_tracker,
- GpuMemoryManager* memory_manager)
- : pid_(pid),
- size_(0),
- hibernated_(false),
- memory_tracker_(memory_tracker),
- memory_manager_(memory_manager) {
-}
-
-GpuMemoryTrackingGroup::~GpuMemoryTrackingGroup() {
- memory_manager_->OnDestroyTrackingGroup(this);
-}
-
-void GpuMemoryTrackingGroup::TrackMemoryAllocatedChange(uint64_t old_size,
- uint64_t new_size) {
- memory_manager_->TrackMemoryAllocatedChange(
- this, old_size, new_size);
-}
-
-bool GpuMemoryTrackingGroup::EnsureGPUMemoryAvailable(uint64_t size_needed) {
- return memory_manager_->EnsureGPUMemoryAvailable(size_needed);
-}
-
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_memory_tracking.h b/chromium/content/common/gpu/gpu_memory_tracking.h
deleted file mode 100644
index 28892832f96..00000000000
--- a/chromium/content/common/gpu/gpu_memory_tracking.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_
-
-#include <stdint.h>
-
-#include "base/process/process.h"
-#include "content/common/content_export.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-
-namespace content {
-
-class GpuMemoryManager;
-
-// All decoders in a context group point to a single GpuMemoryTrackingGroup,
-// which tracks GPU resource consumption for the entire context group.
-class CONTENT_EXPORT GpuMemoryTrackingGroup {
- public:
- ~GpuMemoryTrackingGroup();
- void TrackMemoryAllocatedChange(uint64_t old_size, uint64_t new_size);
- bool EnsureGPUMemoryAvailable(uint64_t size_needed);
- base::ProcessId GetPid() const {
- return pid_;
- }
- uint64_t GetSize() const { return size_; }
- gpu::gles2::MemoryTracker* GetMemoryTracker() const {
- return memory_tracker_;
- }
-
- private:
- friend class GpuMemoryManager;
-
- GpuMemoryTrackingGroup(base::ProcessId pid,
- gpu::gles2::MemoryTracker* memory_tracker,
- GpuMemoryManager* memory_manager);
-
- base::ProcessId pid_;
- uint64_t size_;
-
- // Set and used only during the Manage function, to determine which
- // non-surface clients should be hibernated.
- bool hibernated_;
-
- gpu::gles2::MemoryTracker* memory_tracker_;
- GpuMemoryManager* memory_manager_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_
diff --git a/chromium/content/common/gpu/gpu_memory_uma_stats.h b/chromium/content/common/gpu/gpu_memory_uma_stats.h
deleted file mode 100644
index 15d874f195c..00000000000
--- a/chromium/content/common/gpu/gpu_memory_uma_stats.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_MEMORY_UMA_STATS_H_
-#define CONTENT_COMMON_GPU_GPU_MEMORY_UMA_STATS_H_
-
-#include <stddef.h>
-
-namespace content {
-
-// Memory usage statistics send periodically to the browser process to report
-// in UMA histograms if the GPU process crashes.
-struct GPUMemoryUmaStats {
- GPUMemoryUmaStats()
- : bytes_allocated_current(0),
- bytes_allocated_max(0),
- context_group_count(0) {
- }
-
- // The number of bytes currently allocated.
- size_t bytes_allocated_current;
-
- // The maximum number of bytes ever allocated at once.
- size_t bytes_allocated_max;
-
- // The number of context groups.
- size_t context_group_count;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_MEMORY_UMA_STATS_H_
diff --git a/chromium/content/common/gpu/gpu_messages.h b/chromium/content/common/gpu/gpu_messages.h
deleted file mode 100644
index cfe01a347a7..00000000000
--- a/chromium/content/common/gpu/gpu_messages.h
+++ /dev/null
@@ -1,878 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Multiply-included message file, hence no include guard here, but see below
-// for a much smaller-than-usual include guard section.
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/memory/shared_memory.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "content/common/content_param_traits.h"
-#include "content/common/gpu/gpu_memory_uma_stats.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
-#include "content/common/gpu/gpu_result_codes.h"
-#include "content/common/gpu/gpu_stream_priority.h"
-#include "content/public/common/common_param_traits.h"
-#include "content/public/common/gpu_memory_stats.h"
-#include "gpu/command_buffer/common/capabilities.h"
-#include "gpu/command_buffer/common/command_buffer.h"
-#include "gpu/command_buffer/common/constants.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "gpu/command_buffer/common/value_state.h"
-#include "gpu/config/gpu_info.h"
-#include "gpu/ipc/gpu_command_buffer_traits.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/ipc_message_macros.h"
-#include "media/base/decrypt_config.h"
-#include "media/base/video_types.h"
-#include "media/video/jpeg_decode_accelerator.h"
-#include "media/video/video_decode_accelerator.h"
-#include "media/video/video_encode_accelerator.h"
-#include "ui/events/latency_info.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/swap_result.h"
-#include "ui/gl/gpu_preference.h"
-
-#if defined(OS_ANDROID)
-#include "content/common/android/surface_texture_peer.h"
-#elif defined(OS_MACOSX)
-#include "ui/base/cocoa/remote_layer_api.h"
-#include "ui/gfx/mac/io_surface.h"
-#endif
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-#define IPC_MESSAGE_START GpuMsgStart
-
-IPC_ENUM_TRAITS_MAX_VALUE(content::CauseForGpuLaunch,
- content::CAUSE_FOR_GPU_LAUNCH_MAX_ENUM - 1)
-IPC_ENUM_TRAITS_MAX_VALUE(content::CreateCommandBufferResult,
- content::CREATE_COMMAND_BUFFER_RESULT_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuPreference,
- gfx::GpuPreferenceLast)
-IPC_ENUM_TRAITS_MAX_VALUE(content::GpuStreamPriority,
- content::GpuStreamPriority::LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::SurfaceType,
- gfx::SURFACE_TYPE_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::SwapResult, gfx::SwapResult::SWAP_RESULT_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gpu::MemoryAllocation::PriorityCutoff,
- gpu::MemoryAllocation::CUTOFF_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gpu::error::ContextLostReason,
- gpu::error::kContextLostReasonLast)
-IPC_ENUM_TRAITS_MAX_VALUE(media::JpegDecodeAccelerator::Error,
- media::JpegDecodeAccelerator::LARGEST_ERROR_ENUM)
-IPC_ENUM_TRAITS_MAX_VALUE(media::VideoEncodeAccelerator::Error,
- media::VideoEncodeAccelerator::kErrorMax)
-IPC_ENUM_TRAITS_MIN_MAX_VALUE(media::VideoCodecProfile,
- media::VIDEO_CODEC_PROFILE_MIN,
- media::VIDEO_CODEC_PROFILE_MAX)
-IPC_ENUM_TRAITS_MIN_MAX_VALUE(gpu::CollectInfoResult,
- gpu::kCollectInfoNone,
- gpu::kCollectInfoFatalFailure)
-IPC_ENUM_TRAITS_MIN_MAX_VALUE(gpu::VideoCodecProfile,
- gpu::VIDEO_CODEC_PROFILE_MIN,
- gpu::VIDEO_CODEC_PROFILE_MAX)
-
-IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig)
- IPC_STRUCT_MEMBER(int32_t, share_group_id)
- IPC_STRUCT_MEMBER(int32_t, stream_id)
- IPC_STRUCT_MEMBER(content::GpuStreamPriority, stream_priority)
- IPC_STRUCT_MEMBER(std::vector<int>, attribs)
- IPC_STRUCT_MEMBER(GURL, active_url)
- IPC_STRUCT_MEMBER(gfx::GpuPreference, gpu_preference)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(GpuMsg_EstablishChannel_Params)
- IPC_STRUCT_MEMBER(int, client_id)
- IPC_STRUCT_MEMBER(uint64_t, client_tracing_id)
- IPC_STRUCT_MEMBER(bool, preempts)
- IPC_STRUCT_MEMBER(bool, preempted)
- IPC_STRUCT_MEMBER(bool, allow_future_sync_points)
- IPC_STRUCT_MEMBER(bool, allow_real_time_streams)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBuffer_Params)
- IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferId, id)
- IPC_STRUCT_MEMBER(gfx::Size, size)
- IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
- IPC_STRUCT_MEMBER(gfx::BufferUsage, usage)
- IPC_STRUCT_MEMBER(int32_t, client_id)
- IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, surface_handle)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBufferFromHandle_Params)
- IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferHandle, handle)
- IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferId, id)
- IPC_STRUCT_MEMBER(gfx::Size, size)
- IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
- IPC_STRUCT_MEMBER(int32_t, client_id)
-IPC_STRUCT_END()
-
-#if defined(OS_MACOSX)
-IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
- IPC_STRUCT_MEMBER(int32_t, surface_id)
- // Only one of ca_context_id or io_surface may be non-0.
- IPC_STRUCT_MEMBER(CAContextID, ca_context_id)
- IPC_STRUCT_MEMBER(gfx::ScopedRefCountedIOSurfaceMachPort, io_surface)
- IPC_STRUCT_MEMBER(int32_t, route_id)
- IPC_STRUCT_MEMBER(gfx::Size, size)
- IPC_STRUCT_MEMBER(float, scale_factor)
- IPC_STRUCT_MEMBER(std::vector<ui::LatencyInfo>, latency_info)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(AcceleratedSurfaceMsg_BufferPresented_Params)
- // The vsync parameters, to synchronize presentation with the display.
- IPC_STRUCT_MEMBER(base::TimeTicks, vsync_timebase)
- IPC_STRUCT_MEMBER(base::TimeDelta, vsync_interval)
-IPC_STRUCT_END()
-#endif
-
-IPC_STRUCT_BEGIN(AcceleratedJpegDecoderMsg_Decode_Params)
- IPC_STRUCT_MEMBER(int32_t, input_buffer_id)
- IPC_STRUCT_MEMBER(gfx::Size, coded_size)
- IPC_STRUCT_MEMBER(base::SharedMemoryHandle, input_buffer_handle)
- IPC_STRUCT_MEMBER(uint32_t, input_buffer_size)
- IPC_STRUCT_MEMBER(base::SharedMemoryHandle, output_video_frame_handle)
- IPC_STRUCT_MEMBER(uint32_t, output_buffer_size)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(AcceleratedVideoDecoderMsg_Decode_Params)
- IPC_STRUCT_MEMBER(int32_t, bitstream_buffer_id)
- IPC_STRUCT_MEMBER(base::SharedMemoryHandle, buffer_handle)
- IPC_STRUCT_MEMBER(uint32_t, size)
- IPC_STRUCT_MEMBER(base::TimeDelta, presentation_timestamp)
- IPC_STRUCT_MEMBER(std::string, key_id)
- IPC_STRUCT_MEMBER(std::string, iv)
- IPC_STRUCT_MEMBER(std::vector<media::SubsampleEntry>, subsamples)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(AcceleratedVideoEncoderMsg_Encode_Params)
- IPC_STRUCT_MEMBER(int32_t, frame_id)
- IPC_STRUCT_MEMBER(base::TimeDelta, timestamp)
- IPC_STRUCT_MEMBER(base::SharedMemoryHandle, buffer_handle)
- IPC_STRUCT_MEMBER(uint32_t, buffer_offset)
- IPC_STRUCT_MEMBER(uint32_t, buffer_size)
- IPC_STRUCT_MEMBER(bool, force_keyframe)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(AcceleratedVideoEncoderMsg_Encode_Params2)
- IPC_STRUCT_MEMBER(int32_t, frame_id)
- IPC_STRUCT_MEMBER(base::TimeDelta, timestamp)
- IPC_STRUCT_MEMBER(std::vector<gfx::GpuMemoryBufferHandle>,
- gpu_memory_buffer_handles)
- IPC_STRUCT_MEMBER(gfx::Size, size)
- IPC_STRUCT_MEMBER(bool, force_keyframe)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(GPUCommandBufferConsoleMessage)
- IPC_STRUCT_MEMBER(int32_t, id)
- IPC_STRUCT_MEMBER(std::string, message)
-IPC_STRUCT_END()
-
-#if defined(OS_ANDROID)
-IPC_STRUCT_BEGIN(GpuStreamTextureMsg_MatrixChanged_Params)
- IPC_STRUCT_MEMBER(float, m00)
- IPC_STRUCT_MEMBER(float, m01)
- IPC_STRUCT_MEMBER(float, m02)
- IPC_STRUCT_MEMBER(float, m03)
- IPC_STRUCT_MEMBER(float, m10)
- IPC_STRUCT_MEMBER(float, m11)
- IPC_STRUCT_MEMBER(float, m12)
- IPC_STRUCT_MEMBER(float, m13)
- IPC_STRUCT_MEMBER(float, m20)
- IPC_STRUCT_MEMBER(float, m21)
- IPC_STRUCT_MEMBER(float, m22)
- IPC_STRUCT_MEMBER(float, m23)
- IPC_STRUCT_MEMBER(float, m30)
- IPC_STRUCT_MEMBER(float, m31)
- IPC_STRUCT_MEMBER(float, m32)
- IPC_STRUCT_MEMBER(float, m33)
-IPC_STRUCT_END()
-#endif
-
-IPC_STRUCT_BEGIN(GpuCommandBufferMsg_CreateImage_Params)
- IPC_STRUCT_MEMBER(int32_t, id)
- IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferHandle, gpu_memory_buffer)
- IPC_STRUCT_MEMBER(gfx::Size, size)
- IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
- IPC_STRUCT_MEMBER(uint32_t, internal_format)
- IPC_STRUCT_MEMBER(uint64_t, image_release_count)
-IPC_STRUCT_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::DxDiagNode)
- IPC_STRUCT_TRAITS_MEMBER(values)
- IPC_STRUCT_TRAITS_MEMBER(children)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::GPUInfo::GPUDevice)
- IPC_STRUCT_TRAITS_MEMBER(vendor_id)
- IPC_STRUCT_TRAITS_MEMBER(device_id)
- IPC_STRUCT_TRAITS_MEMBER(active)
- IPC_STRUCT_TRAITS_MEMBER(vendor_string)
- IPC_STRUCT_TRAITS_MEMBER(device_string)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(media::VideoDecodeAccelerator::Config)
- IPC_STRUCT_TRAITS_MEMBER(profile)
- IPC_STRUCT_TRAITS_MEMBER(is_encrypted)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::VideoDecodeAcceleratorSupportedProfile)
- IPC_STRUCT_TRAITS_MEMBER(profile)
- IPC_STRUCT_TRAITS_MEMBER(max_resolution)
- IPC_STRUCT_TRAITS_MEMBER(min_resolution)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::VideoDecodeAcceleratorCapabilities)
- IPC_STRUCT_TRAITS_MEMBER(supported_profiles)
- IPC_STRUCT_TRAITS_MEMBER(flags)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::VideoEncodeAcceleratorSupportedProfile)
- IPC_STRUCT_TRAITS_MEMBER(profile)
- IPC_STRUCT_TRAITS_MEMBER(max_resolution)
- IPC_STRUCT_TRAITS_MEMBER(max_framerate_numerator)
- IPC_STRUCT_TRAITS_MEMBER(max_framerate_denominator)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::GPUInfo)
- IPC_STRUCT_TRAITS_MEMBER(initialization_time)
- IPC_STRUCT_TRAITS_MEMBER(optimus)
- IPC_STRUCT_TRAITS_MEMBER(amd_switchable)
- IPC_STRUCT_TRAITS_MEMBER(lenovo_dcute)
- IPC_STRUCT_TRAITS_MEMBER(gpu)
- IPC_STRUCT_TRAITS_MEMBER(secondary_gpus)
- IPC_STRUCT_TRAITS_MEMBER(adapter_luid)
- IPC_STRUCT_TRAITS_MEMBER(driver_vendor)
- IPC_STRUCT_TRAITS_MEMBER(driver_version)
- IPC_STRUCT_TRAITS_MEMBER(driver_date)
- IPC_STRUCT_TRAITS_MEMBER(pixel_shader_version)
- IPC_STRUCT_TRAITS_MEMBER(vertex_shader_version)
- IPC_STRUCT_TRAITS_MEMBER(max_msaa_samples)
- IPC_STRUCT_TRAITS_MEMBER(machine_model_name)
- IPC_STRUCT_TRAITS_MEMBER(machine_model_version)
- IPC_STRUCT_TRAITS_MEMBER(gl_version)
- IPC_STRUCT_TRAITS_MEMBER(gl_vendor)
- IPC_STRUCT_TRAITS_MEMBER(gl_renderer)
- IPC_STRUCT_TRAITS_MEMBER(gl_extensions)
- IPC_STRUCT_TRAITS_MEMBER(gl_ws_vendor)
- IPC_STRUCT_TRAITS_MEMBER(gl_ws_version)
- IPC_STRUCT_TRAITS_MEMBER(gl_ws_extensions)
- IPC_STRUCT_TRAITS_MEMBER(gl_reset_notification_strategy)
- IPC_STRUCT_TRAITS_MEMBER(can_lose_context)
- IPC_STRUCT_TRAITS_MEMBER(software_rendering)
- IPC_STRUCT_TRAITS_MEMBER(direct_rendering)
- IPC_STRUCT_TRAITS_MEMBER(sandboxed)
- IPC_STRUCT_TRAITS_MEMBER(process_crash_count)
- IPC_STRUCT_TRAITS_MEMBER(in_process_gpu)
- IPC_STRUCT_TRAITS_MEMBER(basic_info_state)
- IPC_STRUCT_TRAITS_MEMBER(context_info_state)
-#if defined(OS_WIN)
- IPC_STRUCT_TRAITS_MEMBER(dx_diagnostics_info_state)
- IPC_STRUCT_TRAITS_MEMBER(dx_diagnostics)
-#endif
- IPC_STRUCT_TRAITS_MEMBER(video_decode_accelerator_capabilities)
- IPC_STRUCT_TRAITS_MEMBER(video_encode_accelerator_supported_profiles)
- IPC_STRUCT_TRAITS_MEMBER(jpeg_decode_accelerator_supported)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats::ProcessStats)
- IPC_STRUCT_TRAITS_MEMBER(video_memory)
- IPC_STRUCT_TRAITS_MEMBER(has_duplicates)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats)
- IPC_STRUCT_TRAITS_MEMBER(process_map)
- IPC_STRUCT_TRAITS_MEMBER(bytes_allocated)
- IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_historical_max)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::GPUMemoryUmaStats)
- IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_current)
- IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_max)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gpu::MemoryAllocation)
- IPC_STRUCT_TRAITS_MEMBER(bytes_limit_when_visible)
- IPC_STRUCT_TRAITS_MEMBER(priority_cutoff_when_visible)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(gfx::GLSurfaceHandle)
- IPC_STRUCT_TRAITS_MEMBER(handle)
- IPC_STRUCT_TRAITS_MEMBER(transport_type)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(media::SubsampleEntry)
- IPC_STRUCT_TRAITS_MEMBER(clear_bytes)
- IPC_STRUCT_TRAITS_MEMBER(cypher_bytes)
-IPC_STRUCT_TRAITS_END()
-
-//------------------------------------------------------------------------------
-// GPU Messages
-// These are messages from the browser to the GPU process.
-
-// Tells the GPU process to initialize itself. The browser explicitly
-// requests this be done so that we are guaranteed that the channel is set
-// up between the browser and GPU process before doing any work that might
-// potentially crash the GPU process. Detection of the child process
-// exiting abruptly is predicated on having the IPC channel set up.
-IPC_MESSAGE_CONTROL0(GpuMsg_Initialize)
-
-// Tells the GPU process to shutdown itself.
-IPC_MESSAGE_CONTROL0(GpuMsg_Finalize)
-
-// Tells the GPU process to create a new channel for communication with a
-// given client. The channel name is returned in a
-// GpuHostMsg_ChannelEstablished message. The client ID is passed so that
-// the GPU process reuses an existing channel to that process if it exists.
-// This ID is a unique opaque identifier generated by the browser process.
-// The client_tracing_id is a unique ID used for the purposes of tracing.
-IPC_MESSAGE_CONTROL1(GpuMsg_EstablishChannel,
- GpuMsg_EstablishChannel_Params /* params */)
-
-// Tells the GPU process to close the channel identified by IPC channel
-// handle. If no channel can be identified, do nothing.
-IPC_MESSAGE_CONTROL1(GpuMsg_CloseChannel,
- IPC::ChannelHandle /* channel_handle */)
-
-// Tells the GPU process to create a new command buffer that renders directly
-// to a native view. A corresponding GpuCommandBufferStub is created.
-IPC_MESSAGE_CONTROL4(GpuMsg_CreateViewCommandBuffer,
- gfx::GLSurfaceHandle, /* compositing_surface */
- int32_t, /* client_id */
- GPUCreateCommandBufferConfig, /* init_params */
- int32_t /* route_id */)
-
-// Tells the GPU process to create a new gpu memory buffer.
-IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBuffer,
- GpuMsg_CreateGpuMemoryBuffer_Params)
-
-// Tells the GPU process to create a new gpu memory buffer from an existing
-// handle.
-IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBufferFromHandle,
- GpuMsg_CreateGpuMemoryBufferFromHandle_Params)
-
-// Tells the GPU process to destroy buffer.
-IPC_MESSAGE_CONTROL3(GpuMsg_DestroyGpuMemoryBuffer,
- gfx::GpuMemoryBufferId, /* id */
- int32_t, /* client_id */
- gpu::SyncToken /* sync_token */)
-
-// Create and initialize a hardware jpeg decoder using the specified route_id.
-// Created decoders should be freed with AcceleratedJpegDecoderMsg_Destroy when
-// no longer needed.
-IPC_SYNC_MESSAGE_CONTROL1_1(GpuMsg_CreateJpegDecoder,
- int32_t /* route_id */,
- bool /* succeeded */)
-
-// Tells the GPU process to create a context for collecting graphics card
-// information.
-IPC_MESSAGE_CONTROL0(GpuMsg_CollectGraphicsInfo)
-
-// Tells the GPU process to report video_memory information for the task manager
-IPC_MESSAGE_CONTROL0(GpuMsg_GetVideoMemoryUsageStats)
-
-#if defined(OS_MACOSX)
-// Tells the GPU process that the browser process has handled the swap
-// buffers or post sub-buffer request.
-IPC_MESSAGE_ROUTED1(AcceleratedSurfaceMsg_BufferPresented,
- AcceleratedSurfaceMsg_BufferPresented_Params)
-#endif
-
-#if defined(OS_ANDROID)
-// Tells the GPU process to wake up the GPU because we're about to draw.
-IPC_MESSAGE_CONTROL0(GpuMsg_WakeUpGpu)
-#endif
-
-// Tells the GPU process to remove all contexts.
-IPC_MESSAGE_CONTROL0(GpuMsg_Clean)
-
-// Tells the GPU process to crash.
-IPC_MESSAGE_CONTROL0(GpuMsg_Crash)
-
-// Tells the GPU process to hang.
-IPC_MESSAGE_CONTROL0(GpuMsg_Hang)
-
-// Tells the GPU process to disable the watchdog thread.
-IPC_MESSAGE_CONTROL0(GpuMsg_DisableWatchdog)
-
-// Tells the GPU process that the browser has seen a GPU switch.
-IPC_MESSAGE_CONTROL0(GpuMsg_GpuSwitched)
-
-// Sends an input event to the gpu service.
-IPC_MESSAGE_CONTROL3(GpuMsg_UpdateValueState,
- int, /* client_id */
- unsigned int, /* target */
- gpu::ValueState /* valuestate */)
-
-//------------------------------------------------------------------------------
-// GPU Host Messages
-// These are messages to the browser.
-
-// A renderer sends this when it wants to create a connection to the GPU
-// process. The browser will create the GPU process if necessary, and will
-// return a handle to the channel via a GpuChannelEstablished message.
-IPC_SYNC_MESSAGE_CONTROL1_3(GpuHostMsg_EstablishGpuChannel,
- content::CauseForGpuLaunch,
- int /* client id */,
- IPC::ChannelHandle /* handle to channel */,
- gpu::GPUInfo /* stats about GPU process*/)
-
-// Response from GPU to a GputMsg_Initialize message.
-IPC_MESSAGE_CONTROL2(GpuHostMsg_Initialized,
- bool /* result */,
- ::gpu::GPUInfo /* gpu_info */)
-
-// Response from GPU to a GpuHostMsg_EstablishChannel message.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_ChannelEstablished,
- IPC::ChannelHandle /* channel_handle */)
-
-// Message from GPU to notify to destroy the channel.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_DestroyChannel, int32_t /* client_id */)
-
-// Message to cache the given shader information.
-IPC_MESSAGE_CONTROL3(GpuHostMsg_CacheShader,
- int32_t /* client_id */,
- std::string /* key */,
- std::string /* shader */)
-
-// Message to the GPU that a shader was loaded from disk.
-IPC_MESSAGE_CONTROL1(GpuMsg_LoadedShader,
- std::string /* encoded shader */)
-
-// Respond from GPU to a GpuMsg_CreateViewCommandBuffer message.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_CommandBufferCreated,
- content::CreateCommandBufferResult /* result */)
-
-// Response from GPU to a GpuMsg_CreateGpuMemoryBuffer message.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_GpuMemoryBufferCreated,
- gfx::GpuMemoryBufferHandle /* handle */)
-
-// Response from GPU to a GpuMsg_CollectGraphicsInfo.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_GraphicsInfoCollected,
- gpu::GPUInfo /* GPU logging stats */)
-
-// Response from GPU to a GpuMsg_GetVideoMemory.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_VideoMemoryUsageStats,
- content::GPUVideoMemoryUsageStats /* GPU memory stats */)
-
-// Message from GPU to add a GPU log message to the about:gpu page.
-IPC_MESSAGE_CONTROL3(GpuHostMsg_OnLogMessage,
- int /*severity*/,
- std::string /* header */,
- std::string /* message */)
-
-
-#if defined(OS_MACOSX)
-// Tells the browser that an accelerated surface has swapped.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
-#endif
-
-#if defined(OS_WIN)
-IPC_MESSAGE_CONTROL2(GpuHostMsg_AcceleratedSurfaceCreatedChildWindow,
- gfx::PluginWindowHandle /* parent_window */,
- gfx::PluginWindowHandle /* child_window */)
-#endif
-
-IPC_MESSAGE_CONTROL1(GpuHostMsg_DidCreateOffscreenContext,
- GURL /* url */)
-
-IPC_MESSAGE_CONTROL3(GpuHostMsg_DidLoseContext,
- bool /* offscreen */,
- gpu::error::ContextLostReason /* reason */,
- GURL /* url */)
-
-IPC_MESSAGE_CONTROL1(GpuHostMsg_DidDestroyOffscreenContext,
- GURL /* url */)
-
-// Tells the browser about GPU memory usage statistics for UMA logging.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_GpuMemoryUmaStats,
- content::GPUMemoryUmaStats /* GPU memory UMA stats */)
-
-// Tells the browser that a context has subscribed to a new target and
-// the browser should start sending the corresponding information
-IPC_MESSAGE_CONTROL2(GpuHostMsg_AddSubscription,
- int32_t /* client_id */,
- unsigned int /* target */)
-
-// Tells the browser that no contexts are subscribed to the target anymore
-// so the browser should stop sending the corresponding information
-IPC_MESSAGE_CONTROL2(GpuHostMsg_RemoveSubscription,
- int32_t /* client_id */,
- unsigned int /* target */)
-
-//------------------------------------------------------------------------------
-// GPU Channel Messages
-// These are messages from a renderer process to the GPU process.
-
-// Tells the GPU process to create a new command buffer that renders to an
-// offscreen frame buffer.
-IPC_SYNC_MESSAGE_CONTROL3_1(GpuChannelMsg_CreateOffscreenCommandBuffer,
- gfx::Size, /* size */
- GPUCreateCommandBufferConfig, /* init_params */
- int32_t, /* route_id */
- bool /* succeeded */)
-
-// The CommandBufferProxy sends this to the GpuCommandBufferStub in its
-// destructor, so that the stub deletes the actual CommandBufferService
-// object that it's hosting.
-IPC_SYNC_MESSAGE_CONTROL1_0(GpuChannelMsg_DestroyCommandBuffer,
- int32_t /* instance_id */)
-
-// Simple NOP message which can be used as fence to ensure all previous sent
-// messages have been received.
-IPC_SYNC_MESSAGE_CONTROL0_0(GpuChannelMsg_Nop)
-
-#if defined(OS_ANDROID)
-//------------------------------------------------------------------------------
-// Stream Texture Messages
-// Tells the GPU process create and send the java surface texture object to
-// the renderer process through the binder thread.
-IPC_MESSAGE_ROUTED2(GpuStreamTextureMsg_EstablishPeer,
- int32_t, /* primary_id */
- int32_t /* secondary_id */)
-
-// Tells the GPU process to set the size of StreamTexture from the given
-// stream Id.
-IPC_MESSAGE_ROUTED1(GpuStreamTextureMsg_SetSize,
- gfx::Size /* size */)
-
-// Tells the service-side instance to start sending frame available
-// notifications.
-IPC_MESSAGE_ROUTED0(GpuStreamTextureMsg_StartListening)
-
-// Inform the renderer that a new frame is available.
-IPC_MESSAGE_ROUTED0(GpuStreamTextureMsg_FrameAvailable)
-
-// Inform the renderer process that the transform matrix has changed.
-IPC_MESSAGE_ROUTED1(GpuStreamTextureMsg_MatrixChanged,
- GpuStreamTextureMsg_MatrixChanged_Params /* params */)
-#endif
-
-//------------------------------------------------------------------------------
-// GPU Command Buffer Messages
-// These are messages between a renderer process to the GPU process relating to
-// a single OpenGL context.
-// Initialize a command buffer with the given number of command entries.
-// Returns the shared memory handle for the command buffer mapped to the
-// calling process.
-IPC_SYNC_MESSAGE_ROUTED1_2(GpuCommandBufferMsg_Initialize,
- base::SharedMemoryHandle /* shared_state */,
- bool /* result */,
- gpu::Capabilities /* capabilities */)
-
-// Sets the shared memory buffer used for commands.
-IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_SetGetBuffer,
- int32_t /* shm_id */)
-
-// Produces the front buffer into a mailbox. This allows another context to draw
-// the output of this context.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ProduceFrontBuffer,
- gpu::Mailbox /* mailbox */)
-
-// Wait until the token is in a specific range, inclusive.
-IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_WaitForTokenInRange,
- int32_t /* start */,
- int32_t /* end */,
- gpu::CommandBuffer::State /* state */)
-
-// Wait until the get offset is in a specific range, inclusive.
-IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_WaitForGetOffsetInRange,
- int32_t /* start */,
- int32_t /* end */,
- gpu::CommandBuffer::State /* state */)
-
-// Asynchronously synchronize the put and get offsets of both processes.
-// Caller passes its current put offset. Current state (including get offset)
-// is returned in shared memory. The input latency info for the current
-// frame is also sent to the GPU process.
-IPC_MESSAGE_ROUTED3(GpuCommandBufferMsg_AsyncFlush,
- int32_t /* put_offset */,
- uint32_t /* flush_count */,
- std::vector<ui::LatencyInfo> /* latency_info */)
-
-// Sent by the GPU process to display messages in the console.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ConsoleMsg,
- GPUCommandBufferConsoleMessage /* msg */)
-
-// Register an existing shared memory transfer buffer. The id that can be
-// used to identify the transfer buffer from a command buffer.
-IPC_MESSAGE_ROUTED3(GpuCommandBufferMsg_RegisterTransferBuffer,
- int32_t /* id */,
- base::SharedMemoryHandle /* transfer_buffer */,
- uint32_t /* size */)
-
-// Destroy a previously created transfer buffer.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_DestroyTransferBuffer, int32_t /* id */)
-
-// Create and initialize a hardware video decoder using the specified route_id.
-// Created decoders should be freed with AcceleratedVideoDecoderMsg_Destroy when
-// no longer needed.
-IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_CreateVideoDecoder,
- media::VideoDecodeAccelerator::Config, /* config */
- int32_t, /* route_id */
- bool /* succeeded */)
-
-// Create and initialize a hardware video encoder using the specified route_id.
-// Created encoders should be freed with AcceleratedVideoEncoderMsg_Destroy when
-// no longer needed.
-IPC_SYNC_MESSAGE_ROUTED5_1(GpuCommandBufferMsg_CreateVideoEncoder,
- media::VideoPixelFormat /* input_format */,
- gfx::Size /* input_visible_size */,
- media::VideoCodecProfile /* output_profile */,
- uint32_t /* initial_bitrate */,
- int32_t, /* route_id */
- bool /* succeeded */)
-
-// Tells the proxy that there was an error and the command buffer had to be
-// destroyed for some reason.
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_Destroyed,
- gpu::error::ContextLostReason, /* reason */
- gpu::error::Error /* error */)
-
-// Tells the browser that SwapBuffers returned and passes latency info
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SwapBuffersCompleted,
- std::vector<ui::LatencyInfo> /* latency_info */,
- gfx::SwapResult /* result */)
-
-// Tells the browser about updated parameters for vsync alignment.
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_UpdateVSyncParameters,
- base::TimeTicks /* timebase */,
- base::TimeDelta /* interval */)
-
-// Inserts a sync point into the channel. This is handled on the IO thread, so
-// can be expected to be reasonably fast, but the sync point is actually
-// retired in order with respect to the other calls. The sync point is shared
-// across channels.
-IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_InsertSyncPoint,
- bool /* retire */,
- uint32_t /* sync_point */)
-
-// Retires the sync point.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_RetireSyncPoint,
- uint32_t /* sync_point */)
-
-// Makes this command buffer signal when a sync point is reached, by sending
-// back a GpuCommandBufferMsg_SignalSyncPointAck message with the same
-// signal_id.
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SignalSyncPoint,
- uint32_t /* sync_point */,
- uint32_t /* signal_id */)
-
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SignalSyncToken,
- gpu::SyncToken /* sync_token */,
- uint32_t /* signal_id */)
-
-// Makes this command buffer signal when a query is reached, by sending
-// back a GpuCommandBufferMsg_SignalSyncPointAck message with the same
-// signal_id.
-IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SignalQuery,
- uint32_t /* query */,
- uint32_t /* signal_id */)
-
-// Response to SignalSyncPoint, SignalSyncToken, and SignalQuery.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_SignalAck, uint32_t /* signal_id */)
-
-// Create an image from an existing gpu memory buffer. The id that can be
-// used to identify the image from a command buffer.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_CreateImage,
- GpuCommandBufferMsg_CreateImage_Params /* params */)
-
-// Destroy a previously created image.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_DestroyImage, int32_t /* id */)
-
-// Attaches an external image stream to the client texture.
-IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_CreateStreamTexture,
- uint32_t, /* client_texture_id */
- int32_t, /* stream_id */
- bool /* succeeded */)
-
-//------------------------------------------------------------------------------
-// Accelerated Video Decoder Messages
-// These messages are sent from Renderer process to GPU process.
-
-// Set a CDM on the decoder to handle encrypted buffers.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_SetCdm,
- int32_t) /* CDM ID */
-
-// Send input buffer for decoding.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Decode,
- AcceleratedVideoDecoderMsg_Decode_Params)
-
-// Give the texture IDs for the textures the decoder will use for output.
-IPC_MESSAGE_ROUTED2(AcceleratedVideoDecoderMsg_AssignPictureBuffers,
- std::vector<int32_t>, /* Picture buffer ID */
- std::vector<uint32_t>) /* Texture ID */
-
-// Send from Renderer process to the GPU process to recycle the given picture
-// buffer for further decoding.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
- int32_t) /* Picture buffer ID */
-
-// Send flush request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Flush)
-
-// Send reset request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Reset)
-
-// Send destroy request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Destroy)
-
-//------------------------------------------------------------------------------
-// Accelerated Video Decoder Host Messages
-// These messages are sent from GPU process to Renderer process.
-// Inform AcceleratedVideoDecoderHost that AcceleratedVideoDecoder has been
-// created.
-
-// Notify the CDM setting result.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_CdmAttached,
- bool) /* success */
-
-// Accelerated video decoder has consumed input buffer from transfer buffer.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
- int32_t) /* Processed buffer ID */
-
-// Allocate video frames for output of the hardware video decoder.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers,
- int32_t, /* Number of video frames to generate */
- gfx::Size, /* Requested size of buffer */
- uint32_t) /* Texture target */
-
-// Decoder reports that a picture is ready and buffer does not need to be passed
-// back to the decoder.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
- int32_t) /* Picture buffer ID */
-
-// Decoder reports that a picture is ready.
-IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderHostMsg_PictureReady,
- int32_t, /* Picture buffer ID */
- int32_t, /* Bitstream buffer ID */
- gfx::Rect, /* Visible rectangle */
- bool) /* Buffer is HW overlay capable */
-
-// Confirm decoder has been flushed.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_FlushDone)
-
-// Confirm decoder has been reset.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_ResetDone)
-
-// Video decoder has encountered an error.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_ErrorNotification,
- uint32_t) /* Error ID */
-
-//------------------------------------------------------------------------------
-// Accelerated Video Encoder Messages
-// These messages are sent from the Renderer process to GPU process.
-
-// Queue a video frame to the encoder to encode. |frame_id| will be returned
-// by AcceleratedVideoEncoderHostMsg_NotifyInputDone.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderMsg_Encode,
- AcceleratedVideoEncoderMsg_Encode_Params)
-
-// Queue a GpuMemoryBuffer backed video frame to the encoder to encode.
-// |frame_id| will be returned by
-// AcceleratedVideoEncoderHostMsg_NotifyInputDone.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderMsg_Encode2,
- AcceleratedVideoEncoderMsg_Encode_Params2)
-
-// Queue a buffer to the encoder for use in returning output. |buffer_id| will
-// be returned by AcceleratedVideoEncoderHostMsg_BitstreamBufferReady.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
- int32_t /* buffer_id */,
- base::SharedMemoryHandle /* buffer_handle */,
- uint32_t /* buffer_size */)
-
-// Request a runtime encoding parameter change.
-IPC_MESSAGE_ROUTED2(AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
- uint32_t /* bitrate */,
- uint32_t /* framerate */)
-
-//------------------------------------------------------------------------------
-// Accelerated Video Encoder Host Messages
-// These messages are sent from GPU process to Renderer process.
-
-// Notify renderer of the input/output buffer requirements of the encoder.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers,
- uint32_t /* input_count */,
- gfx::Size /* input_coded_size */,
- uint32_t /* output_buffer_size */)
-
-// Notify the renderer that the encoder has finished using an input buffer.
-// There is no congruent entry point in the media::VideoEncodeAccelerator
-// interface, in VEA this same done condition is indicated by dropping the
-// reference to the media::VideoFrame passed to VEA::Encode().
-IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderHostMsg_NotifyInputDone,
- int32_t /* frame_id */)
-
-// Notify the renderer that an output buffer has been filled with encoded data.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady,
- int32_t /* bitstream_buffer_id */,
- uint32_t /* payload_size */,
- bool /* key_frame */)
-
-// Report error condition.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoEncoderHostMsg_NotifyError,
- media::VideoEncodeAccelerator::Error /* error */)
-
-// Send destroy request to the encoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoEncoderMsg_Destroy)
-
-//------------------------------------------------------------------------------
-// Accelerated JPEG Decoder Messages
-// These messages are sent from the Browser process to GPU process.
-
-// Decode one JPEG image from shared memory |input_buffer_handle| with size
-// |input_buffer_size|. The input buffer is associated with |input_buffer_id|
-// and the size of JPEG image is |coded_size|. Decoded I420 frame data will
-// be put onto shared memory associated with |output_video_frame_handle|
-// with size limit |output_buffer_size|.
-IPC_MESSAGE_ROUTED1(AcceleratedJpegDecoderMsg_Decode,
- AcceleratedJpegDecoderMsg_Decode_Params)
-
-// Send destroy request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedJpegDecoderMsg_Destroy)
-
-//------------------------------------------------------------------------------
-// Accelerated JPEG Decoder Host Messages
-// These messages are sent from the GPU process to Browser process.
-//
-// Report decode status.
-IPC_MESSAGE_ROUTED2(AcceleratedJpegDecoderHostMsg_DecodeAck,
- int32_t, /* bitstream_buffer_id */
- media::JpegDecodeAccelerator::Error /* error */)
-
-#if defined(OS_CHROMEOS)
-//------------------------------------------------------------------------------
-// Arc Video Accelerator Messages
-// These messages are sent from the Browser process to GPU process.
-
-// Tells the GPU process to create a new channel for communication with
-// ArcVideoAccelerator. The channel is returned using
-// GpuHostMsg_ArcVideoAcceleratorChannelCreated message.
-IPC_MESSAGE_CONTROL0(GpuMsg_CreateArcVideoAcceleratorChannel)
-
-// Tells the GPU process to shutdown arc video service and terminate all
-// instances of ArcVideoAccelerator.
-IPC_MESSAGE_CONTROL0(GpuMsg_ShutdownArcVideoService)
-
-//------------------------------------------------------------------------------
-// Arc Video Accelerator Host Messages
-// These messages are sent from the GPU process to Browser process.
-
-// Response from GPU to a GpuMsg_CreateArcVideoAcceleratorChannel message.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_ArcVideoAcceleratorChannelCreated,
- IPC::ChannelHandle /* handle to channel */)
-#endif
diff --git a/chromium/content/common/gpu/gpu_result_codes.h b/chromium/content/common/gpu/gpu_result_codes.h
deleted file mode 100644
index 11f4272a2ae..00000000000
--- a/chromium/content/common/gpu/gpu_result_codes.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 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 CONTENT_COMMON_GPU_GPU_RESULT_CODES_H_
-#define CONTENT_COMMON_GPU_GPU_RESULT_CODES_H_
-
-namespace content {
-
-enum CreateCommandBufferResult {
- CREATE_COMMAND_BUFFER_SUCCEEDED,
- CREATE_COMMAND_BUFFER_FAILED,
- CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST,
- CREATE_COMMAND_BUFFER_RESULT_LAST =
- CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_RESULT_CODES_H_
diff --git a/chromium/content/common/gpu/gpu_stream_priority.h b/chromium/content/common/gpu/gpu_stream_priority.h
deleted file mode 100644
index 089fb97e04e..00000000000
--- a/chromium/content/common/gpu/gpu_stream_priority.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_GPU_GPU_STREAM_PRIORITY_H_
-#define CONTENT_COMMON_GPU_GPU_STREAM_PRIORITY_H_
-
-namespace content {
-
-enum class GpuStreamPriority {
- REAL_TIME,
- NORMAL,
- LOW,
- INHERIT,
- LAST = INHERIT
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_STREAM_PRIORITY_H_
diff --git a/chromium/content/common/gpu/gpu_surface_lookup.cc b/chromium/content/common/gpu/gpu_surface_lookup.cc
deleted file mode 100644
index 61bbc045e5c..00000000000
--- a/chromium/content/common/gpu/gpu_surface_lookup.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/gpu_surface_lookup.h"
-
-#include "base/logging.h"
-
-namespace content {
-namespace {
-GpuSurfaceLookup* g_instance = NULL;
-} // anonymous namespace
-
-// static
-GpuSurfaceLookup* GpuSurfaceLookup::GetInstance() {
- DCHECK(g_instance);
- return g_instance;
-}
-
-// static
-void GpuSurfaceLookup::InitInstance(GpuSurfaceLookup* lookup) {
- DCHECK(!g_instance || !lookup);
- g_instance = lookup;
-}
-
-#if defined(OS_ANDROID)
-gfx::ScopedJavaSurface GpuSurfaceLookup::AcquireJavaSurface(int surface_id) {
- NOTIMPLEMENTED();
- return gfx::ScopedJavaSurface();
-}
-#endif
-
-} // namespace content
diff --git a/chromium/content/common/gpu/gpu_surface_lookup.h b/chromium/content/common/gpu/gpu_surface_lookup.h
deleted file mode 100644
index c47e7e37901..00000000000
--- a/chromium/content/common/gpu/gpu_surface_lookup.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_SURFACE_LOOKUP_H_
-#define CONTENT_COMMON_GPU_GPU_SURFACE_LOOKUP_H_
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/native_widget_types.h"
-
-#if defined(OS_ANDROID)
-#include "ui/gl/android/scoped_java_surface.h"
-#endif
-
-namespace content {
-
-// This class provides an interface to look up window surface handles
-// that cannot be sent through the IPC channel.
-class CONTENT_EXPORT GpuSurfaceLookup {
- public:
- GpuSurfaceLookup() { }
- virtual ~GpuSurfaceLookup() { }
-
- static GpuSurfaceLookup* GetInstance();
- static void InitInstance(GpuSurfaceLookup* lookup);
-
- virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) = 0;
-
-#if defined(OS_ANDROID)
- virtual gfx::ScopedJavaSurface AcquireJavaSurface(int surface_id);
-#endif
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuSurfaceLookup);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_SURFACE_LOOKUP_H_
diff --git a/chromium/content/common/gpu/gpu_watchdog.h b/chromium/content/common/gpu/gpu_watchdog.h
deleted file mode 100644
index 069aeb72737..00000000000
--- a/chromium/content/common/gpu/gpu_watchdog.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_GPU_WATCHDOG_H_
-#define CONTENT_COMMON_GPU_GPU_WATCHDOG_H_
-
-#include "base/macros.h"
-
-namespace content {
-
-// Interface for objects that monitor the a GPUProcessor's progress. The
-// GPUProcessor will regularly invoke CheckArmed.
-class GpuWatchdog {
- public:
- virtual void CheckArmed() = 0;
-
- protected:
- GpuWatchdog() {}
- virtual ~GpuWatchdog() {};
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GpuWatchdog);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_GPU_WATCHDOG_H_
diff --git a/chromium/content/common/gpu/image_transport_surface.cc b/chromium/content/common/gpu/image_transport_surface.cc
deleted file mode 100644
index 192ec9620b6..00000000000
--- a/chromium/content/common/gpu/image_transport_surface.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/image_transport_surface.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "ui/gfx/vsync_provider.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_switches.h"
-
-namespace content {
-
-ImageTransportSurface::ImageTransportSurface() {}
-
-ImageTransportSurface::~ImageTransportSurface() {}
-
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle) {
- scoped_refptr<gfx::GLSurface> surface;
- if (handle.transport_type == gfx::NULL_TRANSPORT) {
- surface = manager->GetDefaultOffscreenSurface();
- } else {
- surface = CreateNativeSurface(manager, stub, handle);
- if (!surface.get() || !surface->Initialize())
- return NULL;
- }
-
- return surface;
-}
-
-ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle)
- : surface_(surface),
- manager_(manager),
- stub_(stub->AsWeakPtr()),
- handle_(handle) {
- route_id_ = manager_->GenerateRouteID();
- manager_->AddRoute(route_id_, this);
-}
-
-ImageTransportHelper::~ImageTransportHelper() {
- if (stub_.get()) {
- stub_->SetLatencyInfoCallback(
- base::Callback<void(const std::vector<ui::LatencyInfo>&)>());
- }
- manager_->RemoveRoute(route_id_);
-}
-
-bool ImageTransportHelper::Initialize() {
- gpu::gles2::GLES2Decoder* decoder = Decoder();
-
- if (!decoder)
- return false;
-
- stub_->SetLatencyInfoCallback(
- base::Bind(&ImageTransportHelper::SetLatencyInfo,
- base::Unretained(this)));
-
- return true;
-}
-
-bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
-#if defined(OS_MACOSX)
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
- IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BufferPresented,
- OnBufferPresented)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-#else
- NOTREACHED();
- return false;
-#endif
-}
-
-#if defined(OS_MACOSX)
-void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params) {
- // TRACE_EVENT for gpu tests:
- TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffers",
- TRACE_EVENT_SCOPE_THREAD,
- "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
- "width", params.size.width());
- // On mac, handle_ is a surface id. See
- // GpuProcessTransportFactory::CreatePerCompositorData
- params.surface_id = handle_;
- params.route_id = route_id_;
- manager_->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
-}
-#endif
-
-bool ImageTransportHelper::MakeCurrent() {
- gpu::gles2::GLES2Decoder* decoder = Decoder();
- if (!decoder)
- return false;
- return decoder->MakeCurrent();
-}
-
-void ImageTransportHelper::SetSwapInterval(gfx::GLContext* context) {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuVsync))
- context->ForceSwapIntervalZero(true);
- else
- context->SetSwapInterval(1);
-}
-
-gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
- if (!stub_.get())
- return NULL;
- return stub_->decoder();
-}
-
-#if defined(OS_MACOSX)
-void ImageTransportHelper::OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
- surface_->OnBufferPresented(params);
-}
-#endif
-
-void ImageTransportHelper::SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) {
- surface_->SetLatencyInfo(latency_info);
-}
-
-PassThroughImageTransportSurface::PassThroughImageTransportSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::GLSurface* surface)
- : GLSurfaceAdapter(surface),
- did_set_swap_interval_(false),
- weak_ptr_factory_(this) {
- helper_.reset(new ImageTransportHelper(this,
- manager,
- stub,
- gfx::kNullPluginWindow));
-}
-
-bool PassThroughImageTransportSurface::Initialize() {
- // The surface is assumed to have already been initialized.
- return helper_->Initialize();
-}
-
-void PassThroughImageTransportSurface::Destroy() {
- GLSurfaceAdapter::Destroy();
-}
-
-void PassThroughImageTransportSurface::SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) {
- for (size_t i = 0; i < latency_info.size(); i++)
- latency_info_.push_back(latency_info[i]);
-}
-
-gfx::SwapResult PassThroughImageTransportSurface::SwapBuffers() {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
- gfx::SwapResult result = gfx::GLSurfaceAdapter::SwapBuffers();
- FinishSwapBuffers(std::move(latency_info), result);
- return result;
-}
-
-void PassThroughImageTransportSurface::SwapBuffersAsync(
- const GLSurface::SwapCompletionCallback& callback) {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
-
- // We use WeakPtr here to avoid manual management of life time of an instance
- // of this class. Callback will not be called once the instance of this class
- // is destroyed. However, this also means that the callback can be run on
- // the calling thread only.
- gfx::GLSurfaceAdapter::SwapBuffersAsync(base::Bind(
- &PassThroughImageTransportSurface::FinishSwapBuffersAsync,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&latency_info), callback));
-}
-
-gfx::SwapResult PassThroughImageTransportSurface::PostSubBuffer(int x,
- int y,
- int width,
- int height) {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
- gfx::SwapResult result =
- gfx::GLSurfaceAdapter::PostSubBuffer(x, y, width, height);
- FinishSwapBuffers(std::move(latency_info), result);
- return result;
-}
-
-void PassThroughImageTransportSurface::PostSubBufferAsync(
- int x,
- int y,
- int width,
- int height,
- const GLSurface::SwapCompletionCallback& callback) {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
- gfx::GLSurfaceAdapter::PostSubBufferAsync(
- x, y, width, height,
- base::Bind(&PassThroughImageTransportSurface::FinishSwapBuffersAsync,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&latency_info),
- callback));
-}
-
-gfx::SwapResult PassThroughImageTransportSurface::CommitOverlayPlanes() {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
- gfx::SwapResult result = gfx::GLSurfaceAdapter::CommitOverlayPlanes();
- FinishSwapBuffers(std::move(latency_info), result);
- return result;
-}
-
-void PassThroughImageTransportSurface::CommitOverlayPlanesAsync(
- const GLSurface::SwapCompletionCallback& callback) {
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info = StartSwapBuffers();
- gfx::GLSurfaceAdapter::CommitOverlayPlanesAsync(base::Bind(
- &PassThroughImageTransportSurface::FinishSwapBuffersAsync,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&latency_info), callback));
-}
-
-bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
- if (!did_set_swap_interval_) {
- ImageTransportHelper::SetSwapInterval(context);
- did_set_swap_interval_ = true;
- }
- return true;
-}
-
-#if defined(OS_MACOSX)
-void PassThroughImageTransportSurface::OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& /* params */) {
- NOTREACHED();
-}
-#endif
-
-gfx::Size PassThroughImageTransportSurface::GetSize() {
- return GLSurfaceAdapter::GetSize();
-}
-
-PassThroughImageTransportSurface::~PassThroughImageTransportSurface() {}
-
-void PassThroughImageTransportSurface::SendVSyncUpdateIfAvailable() {
- gfx::VSyncProvider* vsync_provider = GetVSyncProvider();
- if (vsync_provider) {
- vsync_provider->GetVSyncParameters(
- base::Bind(&GpuCommandBufferStub::SendUpdateVSyncParameters,
- helper_->stub()->AsWeakPtr()));
- }
-}
-
-scoped_ptr<std::vector<ui::LatencyInfo>>
-PassThroughImageTransportSurface::StartSwapBuffers() {
- // GetVsyncValues before SwapBuffers to work around Mali driver bug:
- // crbug.com/223558.
- SendVSyncUpdateIfAvailable();
-
- base::TimeTicks swap_time = base::TimeTicks::Now();
- for (auto& latency : latency_info_) {
- latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
- }
-
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info(
- new std::vector<ui::LatencyInfo>());
- latency_info->swap(latency_info_);
-
- return latency_info;
-}
-
-void PassThroughImageTransportSurface::FinishSwapBuffers(
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info,
- gfx::SwapResult result) {
- base::TimeTicks swap_ack_time = base::TimeTicks::Now();
- for (auto& latency : *latency_info) {
- latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
- swap_ack_time, 1);
- }
-
- helper_->stub()->SendSwapBuffersCompleted(*latency_info, result);
-}
-
-void PassThroughImageTransportSurface::FinishSwapBuffersAsync(
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info,
- GLSurface::SwapCompletionCallback callback,
- gfx::SwapResult result) {
- FinishSwapBuffers(std::move(latency_info), result);
- callback.Run(result);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/image_transport_surface.h b/chromium/content/common/gpu/image_transport_surface.h
deleted file mode 100644
index bfb68928cf6..00000000000
--- a/chromium/content/common/gpu/image_transport_surface.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_
-#define CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
-#include "ui/events/latency_info.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/swap_result.h"
-#include "ui/gl/gl_surface.h"
-
-#if defined(OS_MACOSX)
-struct AcceleratedSurfaceMsg_BufferPresented_Params;
-struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
-#endif
-
-namespace gfx {
-class GLSurface;
-}
-
-namespace gpu {
-class PreemptionFlag;
-namespace gles2 {
-class GLES2Decoder;
-}
-}
-
-namespace content {
-class GpuChannelManager;
-class GpuCommandBufferStub;
-
-// The GPU process is agnostic as to how it displays results. On some platforms
-// it renders directly to window. On others it renders offscreen and transports
-// the results to the browser process to display. This file provides a simple
-// framework for making the offscreen path seem more like the onscreen path.
-//
-// The ImageTransportSurface class defines an simple interface for events that
-// should be responded to. The factory returns an offscreen surface that looks
-// a lot like an onscreen surface to the GPU process.
-//
-// The ImageTransportSurfaceHelper provides some glue to the outside world:
-// making sure outside events reach the ImageTransportSurface and
-// allowing the ImageTransportSurface to send events to the outside world.
-
-class ImageTransportSurface {
- public:
- ImageTransportSurface();
-
-#if defined(OS_MACOSX)
- virtual void OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) = 0;
-#endif
- virtual void SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) = 0;
-
- // Creates a surface with the given attributes.
- static scoped_refptr<gfx::GLSurface> CreateSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle);
-
-#if defined(OS_MACOSX)
- CONTENT_EXPORT static void SetAllowOSMesaForTesting(bool allow);
-#endif
-
- virtual gfx::Size GetSize() = 0;
-
- protected:
- virtual ~ImageTransportSurface();
-
- private:
- // Creates the appropriate native surface depending on the GL implementation.
- // This will be implemented separately by each platform.
- //
- // This will not be called for texture transport surfaces which are
- // cross-platform. The platform implementation should only create the
- // surface and should not initialize it. On failure, a null scoped_refptr
- // should be returned.
- static scoped_refptr<gfx::GLSurface> CreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle);
-
- DISALLOW_COPY_AND_ASSIGN(ImageTransportSurface);
-};
-
-class ImageTransportHelper
- : public IPC::Listener,
- public base::SupportsWeakPtr<ImageTransportHelper> {
- public:
- // Takes weak pointers to objects that outlive the helper.
- ImageTransportHelper(ImageTransportSurface* surface,
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle);
- ~ImageTransportHelper() override;
-
- bool Initialize();
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& message) override;
-
- // Helper send functions. Caller fills in the surface specific params
- // like size and surface id. The helper fills in the rest.
-#if defined(OS_MACOSX)
- void SendAcceleratedSurfaceBuffersSwapped(
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params);
-#endif
-
- // Make the surface's context current.
- bool MakeCurrent();
-
- // Set the default swap interval on the surface.
- static void SetSwapInterval(gfx::GLContext* context);
-
- GpuChannelManager* manager() const { return manager_; }
- GpuCommandBufferStub* stub() const { return stub_.get(); }
-
- private:
- gpu::gles2::GLES2Decoder* Decoder();
-
- // IPC::Message handlers.
-#if defined(OS_MACOSX)
- void OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params);
-#endif
-
- // Backbuffer resize callback.
- void Resize(gfx::Size size, float scale_factor);
-
- void SetLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
-
- // Weak pointers that point to objects that outlive this helper.
- ImageTransportSurface* surface_;
- GpuChannelManager* manager_;
-
- base::WeakPtr<GpuCommandBufferStub> stub_;
- int32_t route_id_;
- gfx::PluginWindowHandle handle_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageTransportHelper);
-};
-
-// An implementation of ImageTransportSurface that implements GLSurface through
-// GLSurfaceAdapter, thereby forwarding GLSurface methods through to it.
-class PassThroughImageTransportSurface
- : public gfx::GLSurfaceAdapter,
- public ImageTransportSurface {
- public:
- PassThroughImageTransportSurface(GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::GLSurface* surface);
-
- // GLSurface implementation.
- bool Initialize() override;
- void Destroy() override;
- gfx::SwapResult SwapBuffers() override;
- void SwapBuffersAsync(const SwapCompletionCallback& callback) override;
- gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
- void PostSubBufferAsync(int x,
- int y,
- int width,
- int height,
- const SwapCompletionCallback& callback) override;
- gfx::SwapResult CommitOverlayPlanes() override;
- void CommitOverlayPlanesAsync(
- const SwapCompletionCallback& callback) override;
- bool OnMakeCurrent(gfx::GLContext* context) override;
-
- // ImageTransportSurface implementation.
-#if defined(OS_MACOSX)
- void OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) override;
-#endif
- gfx::Size GetSize() override;
- void SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) override;
-
- protected:
- ~PassThroughImageTransportSurface() override;
-
- // If updated vsync parameters can be determined, send this information to
- // the browser.
- virtual void SendVSyncUpdateIfAvailable();
-
- scoped_ptr<std::vector<ui::LatencyInfo>> StartSwapBuffers();
- void FinishSwapBuffers(scoped_ptr<std::vector<ui::LatencyInfo>> latency_info,
- gfx::SwapResult result);
- void FinishSwapBuffersAsync(
- scoped_ptr<std::vector<ui::LatencyInfo>> latency_info,
- GLSurface::SwapCompletionCallback callback,
- gfx::SwapResult result);
-
- ImageTransportHelper* GetHelper() { return helper_.get(); }
-
- private:
- scoped_ptr<ImageTransportHelper> helper_;
- bool did_set_swap_interval_;
- std::vector<ui::LatencyInfo> latency_info_;
- base::WeakPtrFactory<PassThroughImageTransportSurface> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PassThroughImageTransportSurface);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_
diff --git a/chromium/content/common/gpu/image_transport_surface_android.cc b/chromium/content/common/gpu/image_transport_surface_android.cc
deleted file mode 100644
index 79a16c0bbdf..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_android.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/image_transport_surface.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_channel_manager.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
-#include "content/common/gpu/gpu_surface_lookup.h"
-#include "content/public/common/content_switches.h"
-#include "ui/gl/gl_surface_egl.h"
-
-namespace content {
-
-// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle) {
- DCHECK(GpuSurfaceLookup::GetInstance());
- DCHECK_EQ(handle.transport_type, gfx::NATIVE_DIRECT);
- ANativeWindow* window =
- GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(handle.handle);
- if (!window) {
- LOG(WARNING) << "Failed to acquire native widget.";
- return scoped_refptr<gfx::GLSurface>();
- }
- scoped_refptr<gfx::GLSurface> surface =
- new gfx::NativeViewGLSurfaceEGL(window);
- bool initialize_success = surface->Initialize();
- ANativeWindow_release(window);
- if (!initialize_success)
- return scoped_refptr<gfx::GLSurface>();
-
- return scoped_refptr<gfx::GLSurface>(
- new PassThroughImageTransportSurface(manager, stub, surface.get()));
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/image_transport_surface_linux.cc b/chromium/content/common/gpu/image_transport_surface_linux.cc
deleted file mode 100644
index db36efea135..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_linux.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 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 "content/common/gpu/image_transport_surface.h"
-
-namespace content {
-
-// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle) {
- DCHECK(handle.handle);
- DCHECK(handle.transport_type == gfx::NATIVE_DIRECT);
- scoped_refptr<gfx::GLSurface> surface;
-#if defined(USE_OZONE)
- surface = gfx::GLSurface::CreateSurfacelessViewGLSurface(handle.handle);
-#endif
- if (!surface)
- surface = gfx::GLSurface::CreateViewGLSurface(handle.handle);
- if (!surface)
- return surface;
- return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
- manager, stub, surface.get()));
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/image_transport_surface_mac.mm b/chromium/content/common/gpu/image_transport_surface_mac.mm
deleted file mode 100644
index 1059589b084..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_mac.mm
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2014 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 "content/common/gpu/image_transport_surface.h"
-
-#include "base/macros.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface_osmesa.h"
-
-namespace content {
-
-scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle);
-
-namespace {
-
-// A subclass of GLSurfaceOSMesa that doesn't print an error message when
-// SwapBuffers() is called.
-class DRTSurfaceOSMesa : public gfx::GLSurfaceOSMesa {
- public:
- // Size doesn't matter, the surface is resized to the right size later.
- DRTSurfaceOSMesa()
- : GLSurfaceOSMesa(gfx::OSMesaSurfaceFormatRGBA, gfx::Size(1, 1)) {}
-
- // Implement a subset of GLSurface.
- gfx::SwapResult SwapBuffers() override;
-
- private:
- ~DRTSurfaceOSMesa() override {}
- DISALLOW_COPY_AND_ASSIGN(DRTSurfaceOSMesa);
-};
-
-gfx::SwapResult DRTSurfaceOSMesa::SwapBuffers() {
- return gfx::SwapResult::SWAP_ACK;
-}
-
-bool g_allow_os_mesa = false;
-
-} // namespace
-
-// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& surface_handle) {
- DCHECK(surface_handle.transport_type == gfx::NATIVE_DIRECT ||
- surface_handle.transport_type == gfx::NULL_TRANSPORT);
-
- switch (gfx::GetGLImplementation()) {
- case gfx::kGLImplementationDesktopGL:
- case gfx::kGLImplementationDesktopGLCoreProfile:
- case gfx::kGLImplementationAppleGL:
- return ImageTransportSurfaceCreateNativeSurface(manager, stub,
- surface_handle.handle);
- default:
- // Content shell in DRT mode spins up a gpu process which needs an
- // image transport surface, but that surface isn't used to read pixel
- // baselines. So this is mostly a dummy surface.
- if (!g_allow_os_mesa) {
- NOTREACHED();
- return scoped_refptr<gfx::GLSurface>();
- }
- scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa());
- if (!surface.get() || !surface->Initialize())
- return surface;
- return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
- manager, stub, surface.get()));
- }
-}
-
-// static
-void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) {
- g_allow_os_mesa = allow;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/image_transport_surface_overlay_mac.h b/chromium/content/common/gpu/image_transport_surface_overlay_mac.h
deleted file mode 100644
index 2103bbf7108..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_overlay_mac.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_OVERLAY_MAC_H_
-#define CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_OVERLAY_MAC_H_
-
-#include <list>
-#include <vector>
-
-#import "base/mac/scoped_nsobject.h"
-#include "base/timer/timer.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
-#include "content/common/gpu/image_transport_surface.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/gpu_switching_observer.h"
-
-@class CAContext;
-@class CALayer;
-
-namespace content {
-
-class CALayerTree;
-class CALayerPartialDamageTree;
-
-class ImageTransportSurfaceOverlayMac : public gfx::GLSurface,
- public ImageTransportSurface,
- public ui::GpuSwitchingObserver {
- public:
- ImageTransportSurfaceOverlayMac(GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle);
-
- // GLSurface implementation
- bool Initialize() override;
- void Destroy() override;
- bool Resize(const gfx::Size& size,
- float scale_factor,
- bool has_alpha) override;
- bool IsOffscreen() override;
- gfx::SwapResult SwapBuffers() override;
- gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
- bool SupportsPostSubBuffer() override;
- gfx::Size GetSize() override;
- void* GetHandle() override;
- bool OnMakeCurrent(gfx::GLContext* context) override;
- bool SetBackbufferAllocation(bool allocated) override;
- bool ScheduleOverlayPlane(int z_order,
- gfx::OverlayTransform transform,
- gl::GLImage* image,
- const gfx::Rect& bounds_rect,
- const gfx::RectF& crop_rect) override;
- bool ScheduleCALayer(gl::GLImage* contents_image,
- const gfx::RectF& contents_rect,
- float opacity,
- unsigned background_color,
- unsigned edge_aa_mask,
- const gfx::RectF& rect,
- bool is_clipped,
- const gfx::RectF& clip_rect,
- const gfx::Transform& transform,
- int sorting_context_id) override;
- bool IsSurfaceless() const override;
-
- // ImageTransportSurface implementation
- void OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) override;
- void SetLatencyInfo(const std::vector<ui::LatencyInfo>&) override;
-
- // ui::GpuSwitchingObserver implementation.
- void OnGpuSwitched() override;
-
- private:
- class PendingSwap;
- class OverlayPlane;
-
- ~ImageTransportSurfaceOverlayMac() override;
-
- gfx::SwapResult SwapBuffersInternal(const gfx::Rect& pixel_damage_rect);
-
- // Returns true if the front of |pending_swaps_| has completed, or has timed
- // out by |now|.
- bool IsFirstPendingSwapReadyToDisplay(
- const base::TimeTicks& now);
- // Sets the CALayer contents to the IOSurface for the front of
- // |pending_swaps_|, and removes it from the queue.
- void DisplayFirstPendingSwapImmediately();
- // Force that all of |pending_swaps_| displayed immediately, and the list be
- // cleared.
- void DisplayAndClearAllPendingSwaps();
- // Callback issued during the next vsync period ofter a SwapBuffers call,
- // to check if the swap is completed, and display the frame. Note that if
- // another SwapBuffers happens before this callback, the pending swap will
- // be tested at that time, too.
- void CheckPendingSwapsCallback();
- // Function to post the above callback. The argument |now| is passed as an
- // argument to avoid redundant calls to base::TimeTicks::Now.
- void PostCheckPendingSwapsCallbackIfNeeded(const base::TimeTicks& now);
-
- // Return the time of |interval_fraction| of the way through the next
- // vsync period that starts after |from|. If the vsync parameters are not
- // valid then return |from|.
- base::TimeTicks GetNextVSyncTimeAfter(
- const base::TimeTicks& from, double interval_fraction);
-
- scoped_ptr<ImageTransportHelper> helper_;
- bool use_remote_layer_api_;
- base::scoped_nsobject<CAContext> ca_context_;
- base::scoped_nsobject<CALayer> ca_root_layer_;
-
- gfx::Size pixel_size_;
- float scale_factor_;
- std::vector<ui::LatencyInfo> latency_info_;
-
- // The renderer ID that all contexts made current to this surface should be
- // targeting.
- GLint gl_renderer_id_;
-
- // Planes that have been scheduled, but have not had a subsequent SwapBuffers
- // call made yet.
- scoped_ptr<CALayerPartialDamageTree> pending_partial_damage_tree_;
- scoped_ptr<CALayerTree> pending_ca_layer_tree_;
-
- // A queue of all frames that have been created by SwapBuffersInternal but
- // have not yet been displayed. This queue is checked at the beginning of
- // every swap and also by a callback.
- std::deque<linked_ptr<PendingSwap>> pending_swaps_;
-
- // The planes that are currently being displayed on the screen.
- scoped_ptr<CALayerPartialDamageTree> current_partial_damage_tree_;
- scoped_ptr<CALayerTree> current_ca_layer_tree_;
-
- // The time of the last swap was issued. If this is more than two vsyncs, then
- // use the simpler non-smooth animation path.
- base::TimeTicks last_swap_time_;
-
- // The vsync information provided by the browser.
- bool vsync_parameters_valid_;
- base::TimeTicks vsync_timebase_;
- base::TimeDelta vsync_interval_;
-
- base::Timer display_pending_swap_timer_;
- base::WeakPtrFactory<ImageTransportSurfaceOverlayMac> weak_factory_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_OVERLAY_MAC_H_
diff --git a/chromium/content/common/gpu/image_transport_surface_overlay_mac.mm b/chromium/content/common/gpu/image_transport_surface_overlay_mac.mm
deleted file mode 100644
index 1b0e3372e2d..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_overlay_mac.mm
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/image_transport_surface_overlay_mac.h"
-
-#include <CoreGraphics/CoreGraphics.h>
-#include <IOSurface/IOSurface.h>
-#include <OpenGL/CGLRenderers.h>
-#include <OpenGL/CGLTypes.h>
-#include <OpenGL/gl.h>
-#include <stddef.h>
-
-#include <algorithm>
-
-// This type consistently causes problem on Mac, and needs to be dealt with
-// in a systemic way.
-// http://crbug.com/517208
-#ifndef GL_OES_EGL_image
-typedef void* GLeglImageOES;
-#endif
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/ca_layer_partial_damage_tree_mac.h"
-#include "content/common/gpu/ca_layer_tree_mac.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ui/accelerated_widget_mac/io_surface_context.h"
-#include "ui/base/cocoa/animation_utils.h"
-#include "ui/base/cocoa/remote_layer_api.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_fence.h"
-#include "ui/gl/gl_image_io_surface.h"
-#include "ui/gl/gpu_switching_manager.h"
-#include "ui/gl/scoped_api.h"
-#include "ui/gl/scoped_cgl.h"
-
-namespace {
-
-// Don't let a frame draw until 5% of the way through the next vsync interval
-// after the call to SwapBuffers. This slight offset is to ensure that skew
-// doesn't result in the frame being presented to the previous vsync interval.
-const double kVSyncIntervalFractionForEarliestDisplay = 0.05;
-
-// After doing a glFlush and putting in a fence in SwapBuffers, post a task to
-// query the fence 50% of the way through the next vsync interval. If we are
-// trying to animate smoothly, then want to query the fence at the next
-// SwapBuffers. For this reason we schedule the callback for a long way into
-// the next frame.
-const double kVSyncIntervalFractionForDisplayCallback = 0.5;
-
-// If swaps arrive regularly and nearly at the vsync rate, then attempt to
-// make animation smooth (each frame is shown for one vsync interval) by sending
-// them to the window server only when their GL work completes. If frames are
-// not coming in with each vsync, then just throw them at the window server as
-// they come.
-const double kMaximumVSyncsBetweenSwapsForSmoothAnimation = 1.5;
-
-void CheckGLErrors(const char* msg) {
- GLenum gl_error;
- while ((gl_error = glGetError()) != GL_NO_ERROR) {
- LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error;
- }
-}
-
-void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) {
-}
-
-} // namespace
-
-@interface CALayer(Private)
--(void)setContentsChanged;
-@end
-
-namespace content {
-
-scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle) {
- return new ImageTransportSurfaceOverlayMac(manager, stub, handle);
-}
-
-class ImageTransportSurfaceOverlayMac::PendingSwap {
- public:
- PendingSwap() {}
- ~PendingSwap() { DCHECK(!gl_fence); }
-
- gfx::Size pixel_size;
- float scale_factor;
- gfx::Rect pixel_damage_rect;
-
- scoped_ptr<CALayerPartialDamageTree> partial_damage_tree;
- scoped_ptr<CALayerTree> ca_layer_tree;
- std::vector<ui::LatencyInfo> latency_info;
-
- // A fence object, and the CGL context it was issued in.
- base::ScopedTypeRef<CGLContextObj> cgl_context;
- scoped_ptr<gfx::GLFence> gl_fence;
-
- // The earliest time that this frame may be drawn. A frame is not allowed
- // to draw until a fraction of the way through the vsync interval after its
- // This extra latency is to allow wiggle-room for smoothness.
- base::TimeTicks earliest_display_time_allowed;
-
- // The time that this will wake up and draw, if a following swap does not
- // cause it to draw earlier.
- base::TimeTicks target_display_time;
-};
-
-ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle)
- : use_remote_layer_api_(ui::RemoteLayerAPISupported()),
- scale_factor_(1),
- gl_renderer_id_(0),
- vsync_parameters_valid_(false),
- display_pending_swap_timer_(true, false),
- weak_factory_(this) {
- helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
- ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
-}
-
-ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() {
- ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
- Destroy();
-}
-
-bool ImageTransportSurfaceOverlayMac::Initialize() {
- if (!helper_->Initialize())
- return false;
-
- // Create the CAContext to send this to the GPU process, and the layer for
- // the context.
- if (use_remote_layer_api_) {
- CGSConnectionID connection_id = CGSMainConnectionID();
- ca_context_.reset([
- [CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
- ca_root_layer_.reset([[CALayer alloc] init]);
- [ca_root_layer_ setGeometryFlipped:YES];
- [ca_root_layer_ setOpaque:YES];
- [ca_context_ setLayer:ca_root_layer_];
- }
- return true;
-}
-
-void ImageTransportSurfaceOverlayMac::Destroy() {
- DisplayAndClearAllPendingSwaps();
-
- current_partial_damage_tree_.reset();
- current_ca_layer_tree_.reset();
-}
-
-bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
- return false;
-}
-
-gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
- const gfx::Rect& pixel_damage_rect) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal");
-
- // Use the same concept of 'now' for the entire function. The duration of
- // this function only affect the result if this function lasts across a vsync
- // boundary, in which case smooth animation is out the window anyway.
- const base::TimeTicks now = base::TimeTicks::Now();
-
- // Decide if the frame should be drawn immediately, or if we should wait until
- // its work finishes before drawing immediately.
- bool display_immediately = false;
- if (vsync_parameters_valid_ &&
- now - last_swap_time_ >
- kMaximumVSyncsBetweenSwapsForSmoothAnimation * vsync_interval_) {
- display_immediately = true;
- }
- last_swap_time_ = now;
-
- // If the previous swap is ready to display, do it before flushing the
- // new swap. It is desirable to always be hitting this path when trying to
- // animate smoothly with vsync.
- if (!pending_swaps_.empty()) {
- if (IsFirstPendingSwapReadyToDisplay(now))
- DisplayFirstPendingSwapImmediately();
- }
-
- // The remainder of the function will populate the PendingSwap structure and
- // then enqueue it.
- linked_ptr<PendingSwap> new_swap(new PendingSwap);
- new_swap->pixel_size = pixel_size_;
- new_swap->scale_factor = scale_factor_;
- new_swap->pixel_damage_rect = pixel_damage_rect;
- new_swap->partial_damage_tree.swap(pending_partial_damage_tree_);
- new_swap->ca_layer_tree.swap(pending_ca_layer_tree_);
- new_swap->latency_info.swap(latency_info_);
-
- // A flush is required to ensure that all content appears in the layer.
- {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFlush");
- CheckGLErrors("before flushing frame");
- new_swap->cgl_context.reset(CGLGetCurrentContext(),
- base::scoped_policy::RETAIN);
- if (gfx::GLFence::IsSupported() && !display_immediately)
- new_swap->gl_fence.reset(gfx::GLFence::Create());
- else
- glFlush();
- CheckGLErrors("while flushing frame");
- }
-
- // Compute the deadlines for drawing this frame.
- if (display_immediately) {
- new_swap->earliest_display_time_allowed = now;
- new_swap->target_display_time = now;
- } else {
- new_swap->earliest_display_time_allowed =
- GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForEarliestDisplay);
- new_swap->target_display_time =
- GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForDisplayCallback);
- }
-
- pending_swaps_.push_back(new_swap);
- if (display_immediately)
- DisplayFirstPendingSwapImmediately();
- else
- PostCheckPendingSwapsCallbackIfNeeded(now);
- return gfx::SwapResult::SWAP_ACK;
-}
-
-bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay(
- const base::TimeTicks& now) {
- DCHECK(!pending_swaps_.empty());
- linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
- // Frames are disallowed from drawing until the vsync interval after their
- // swap is issued.
- if (now < swap->earliest_display_time_allowed)
- return false;
-
- // If we've passed that marker, then wait for the work behind the fence to
- // complete.
- if (swap->gl_fence) {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
- CheckGLErrors("before waiting on fence");
- if (!swap->gl_fence->HasCompleted()) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::ClientWait");
- swap->gl_fence->ClientWait();
- }
- swap->gl_fence.reset();
- CheckGLErrors("after waiting on fence");
- }
- return true;
-}
-
-void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately");
- DCHECK(!pending_swaps_.empty());
- linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
- // If there is a fence for this object, delete it.
- if (swap->gl_fence) {
- gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
- gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
- CheckGLErrors("before deleting active fence");
- swap->gl_fence.reset();
- CheckGLErrors("while deleting active fence");
- }
-
- // Update the CALayer hierarchy.
- {
- gfx::RectF pixel_damage_rect = gfx::RectF(swap->pixel_damage_rect);
- ScopedCAActionDisabler disabler;
- if (swap->ca_layer_tree) {
- swap->ca_layer_tree->CommitScheduledCALayers(
- ca_root_layer_.get(), std::move(current_ca_layer_tree_),
- swap->scale_factor);
- current_ca_layer_tree_.swap(swap->ca_layer_tree);
- current_partial_damage_tree_.reset();
- } else if (swap->partial_damage_tree) {
- swap->partial_damage_tree->CommitCALayers(
- ca_root_layer_.get(), std::move(current_partial_damage_tree_),
- swap->scale_factor, swap->pixel_damage_rect);
- current_partial_damage_tree_.swap(swap->partial_damage_tree);
- current_ca_layer_tree_.reset();
- } else {
- TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers");
- [ca_root_layer_ setSublayers:nil];
- current_partial_damage_tree_.reset();
- current_ca_layer_tree_.reset();
- }
- swap->ca_layer_tree.reset();
- swap->partial_damage_tree.reset();
- }
-
- // Update the latency info to reflect the swap time.
- base::TimeTicks swap_time = base::TimeTicks::Now();
- for (auto latency_info : swap->latency_info) {
- latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
- latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
- swap_time, 1);
- }
-
- // Send acknowledgement to the browser.
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
- if (use_remote_layer_api_) {
- params.ca_context_id = [ca_context_ contextId];
- } else if (current_partial_damage_tree_) {
- params.io_surface.reset(IOSurfaceCreateMachPort(
- current_partial_damage_tree_->RootLayerIOSurface()));
- }
- params.size = swap->pixel_size;
- params.scale_factor = swap->scale_factor;
- params.latency_info.swap(swap->latency_info);
- helper_->SendAcceleratedSurfaceBuffersSwapped(params);
-
- // Remove this from the queue, and reset any callback timers.
- pending_swaps_.pop_front();
-}
-
-void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps");
- while (!pending_swaps_.empty())
- DisplayFirstPendingSwapImmediately();
-}
-
-void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback");
-
- if (pending_swaps_.empty())
- return;
-
- const base::TimeTicks now = base::TimeTicks::Now();
- if (IsFirstPendingSwapReadyToDisplay(now))
- DisplayFirstPendingSwapImmediately();
- PostCheckPendingSwapsCallbackIfNeeded(now);
-}
-
-void ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded(
- const base::TimeTicks& now) {
- TRACE_EVENT0("gpu",
- "ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded");
-
- if (pending_swaps_.empty()) {
- display_pending_swap_timer_.Stop();
- } else {
- display_pending_swap_timer_.Start(
- FROM_HERE,
- pending_swaps_.front()->target_display_time - now,
- base::Bind(&ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback,
- weak_factory_.GetWeakPtr()));
- }
-}
-
-gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() {
- return SwapBuffersInternal(
- gfx::Rect(0, 0, pixel_size_.width(), pixel_size_.height()));
-}
-
-gfx::SwapResult ImageTransportSurfaceOverlayMac::PostSubBuffer(int x,
- int y,
- int width,
- int height) {
- return SwapBuffersInternal(gfx::Rect(x, y, width, height));
-}
-
-bool ImageTransportSurfaceOverlayMac::SupportsPostSubBuffer() {
- return true;
-}
-
-gfx::Size ImageTransportSurfaceOverlayMac::GetSize() {
- return gfx::Size();
-}
-
-void* ImageTransportSurfaceOverlayMac::GetHandle() {
- return nullptr;
-}
-
-bool ImageTransportSurfaceOverlayMac::OnMakeCurrent(gfx::GLContext* context) {
- // Ensure that the context is on the appropriate GL renderer. The GL renderer
- // will generally only change when the GPU changes.
- if (gl_renderer_id_ && context)
- context->share_group()->SetRendererID(gl_renderer_id_);
- return true;
-}
-
-bool ImageTransportSurfaceOverlayMac::SetBackbufferAllocation(bool allocated) {
- if (!allocated) {
- DisplayAndClearAllPendingSwaps();
- last_swap_time_ = base::TimeTicks();
- }
- return true;
-}
-
-bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane(
- int z_order,
- gfx::OverlayTransform transform,
- gl::GLImage* image,
- const gfx::Rect& pixel_frame_rect,
- const gfx::RectF& crop_rect) {
- if (transform != gfx::OVERLAY_TRANSFORM_NONE) {
- DLOG(ERROR) << "Invalid overlay plane transform.";
- return false;
- }
- if (z_order) {
- DLOG(ERROR) << "Invalid non-zero Z order.";
- return false;
- }
- if (pending_partial_damage_tree_) {
- DLOG(ERROR) << "Only one overlay per swap is allowed.";
- return false;
- }
- pending_partial_damage_tree_.reset(new CALayerPartialDamageTree(
- use_remote_layer_api_,
- static_cast<gl::GLImageIOSurface*>(image)->io_surface(),
- pixel_frame_rect));
- return true;
-}
-
-bool ImageTransportSurfaceOverlayMac::ScheduleCALayer(
- gl::GLImage* contents_image,
- const gfx::RectF& contents_rect,
- float opacity,
- unsigned background_color,
- unsigned edge_aa_mask,
- const gfx::RectF& rect,
- bool is_clipped,
- const gfx::RectF& clip_rect,
- const gfx::Transform& transform,
- int sorting_context_id) {
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
- if (contents_image) {
- io_surface =
- static_cast<gl::GLImageIOSurface*>(contents_image)->io_surface();
- }
- if (!pending_ca_layer_tree_)
- pending_ca_layer_tree_.reset(new CALayerTree);
- return pending_ca_layer_tree_->ScheduleCALayer(
- is_clipped, gfx::ToEnclosingRect(clip_rect), sorting_context_id,
- transform, io_surface, contents_rect, gfx::ToEnclosingRect(rect),
- background_color, edge_aa_mask, opacity);
-}
-
-bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const {
- return true;
-}
-
-void ImageTransportSurfaceOverlayMac::OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
- vsync_timebase_ = params.vsync_timebase;
- vsync_interval_ = params.vsync_interval;
- vsync_parameters_valid_ = (vsync_interval_ != base::TimeDelta());
-
- // Compute |vsync_timebase_| to be the first vsync after time zero.
- if (vsync_parameters_valid_) {
- vsync_timebase_ -=
- vsync_interval_ *
- ((vsync_timebase_ - base::TimeTicks()) / vsync_interval_);
- }
-}
-
-bool ImageTransportSurfaceOverlayMac::Resize(const gfx::Size& pixel_size,
- float scale_factor,
- bool has_alpha) {
- // Flush through any pending frames.
- DisplayAndClearAllPendingSwaps();
- pixel_size_ = pixel_size;
- scale_factor_ = scale_factor;
- return true;
-}
-
-void ImageTransportSurfaceOverlayMac::SetLatencyInfo(
- const std::vector<ui::LatencyInfo>& latency_info) {
- latency_info_.insert(
- latency_info_.end(), latency_info.begin(), latency_info.end());
-}
-
-void ImageTransportSurfaceOverlayMac::OnGpuSwitched() {
- // Create a new context, and use the GL renderer ID that the new context gets.
- scoped_refptr<ui::IOSurfaceContext> context_on_new_gpu =
- ui::IOSurfaceContext::Get(ui::IOSurfaceContext::kCALayerContext);
- if (!context_on_new_gpu)
- return;
- GLint context_renderer_id = -1;
- if (CGLGetParameter(context_on_new_gpu->cgl_context(),
- kCGLCPCurrentRendererID,
- &context_renderer_id) != kCGLNoError) {
- LOG(ERROR) << "Failed to create test context after GPU switch";
- return;
- }
- gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask;
-
- // Post a task holding a reference to the new GL context. The reason for
- // this is to avoid creating-then-destroying the context for every image
- // transport surface that is observing the GPU switch.
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu));
-}
-
-base::TimeTicks ImageTransportSurfaceOverlayMac::GetNextVSyncTimeAfter(
- const base::TimeTicks& from, double interval_fraction) {
- if (!vsync_parameters_valid_)
- return from;
-
- // Compute the previous vsync time.
- base::TimeTicks previous_vsync =
- vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) +
- vsync_timebase_;
-
- // Return |interval_fraction| through the next vsync.
- return previous_vsync + (1 + interval_fraction) * vsync_interval_;
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/image_transport_surface_win.cc b/chromium/content/common/gpu/image_transport_surface_win.cc
deleted file mode 100644
index 15f43d2a00f..00000000000
--- a/chromium/content/common/gpu/image_transport_surface_win.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 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 "content/common/gpu/image_transport_surface.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/win/windows_version.h"
-#include "content/common/gpu/child_window_surface_win.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/public/common/content_switches.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface_egl.h"
-#include "ui/gl/vsync_provider_win.h"
-
-namespace content {
-
-// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle) {
- DCHECK(handle.handle);
- DCHECK_EQ(handle.transport_type, gfx::NATIVE_DIRECT);
-
- scoped_refptr<gfx::GLSurface> surface;
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
- gfx::GLSurfaceEGL::IsDirectCompositionSupported()) {
- scoped_refptr<ChildWindowSurfaceWin> egl_surface(
- new ChildWindowSurfaceWin(manager, handle.handle));
- surface = egl_surface;
-
- // TODO(jbauman): Get frame statistics from DirectComposition
- scoped_ptr<gfx::VSyncProvider> vsync_provider(
- new gfx::VSyncProviderWin(handle.handle));
- if (!egl_surface->Initialize(std::move(vsync_provider)))
- return nullptr;
- } else {
- surface = gfx::GLSurface::CreateViewGLSurface(handle.handle);
- }
-
- return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
- manager, stub, surface.get()));
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/media/OWNERS b/chromium/content/common/gpu/media/OWNERS
index 633a1877529..9999d737345 100644
--- a/chromium/content/common/gpu/media/OWNERS
+++ b/chromium/content/common/gpu/media/OWNERS
@@ -2,3 +2,16 @@ dalecurtis@chromium.org
posciak@chromium.org
sandersd@chromium.org
wuchengli@chromium.org
+
+# For security review of IPC message files.
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=dcheng@chromium.org
+per-file *_messages*.h=inferno@chromium.org
+per-file *_messages*.h=jln@chromium.org
+per-file *_messages*.h=jschuh@chromium.org
+per-file *_messages*.h=kenrb@chromium.org
+per-file *_messages*.h=mkwst@chromium.org
+per-file *_messages*.h=nasko@chromium.org
+per-file *_messages*.h=palmer@chromium.org
+per-file *_messages*.h=tsepez@chromium.org
+per-file *_messages*.h=wfh@chromium.org
diff --git a/chromium/content/common/gpu/media/android_copying_backing_strategy.cc b/chromium/content/common/gpu/media/android_copying_backing_strategy.cc
index f80a16f3d72..b5216154829 100644
--- a/chromium/content/common/gpu/media/android_copying_backing_strategy.cc
+++ b/chromium/content/common/gpu/media/android_copying_backing_strategy.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "content/common/gpu/media/avda_return_on_failure.h"
+#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "media/base/limits.h"
@@ -17,24 +18,47 @@
namespace content {
-const static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
-
-AndroidCopyingBackingStrategy::AndroidCopyingBackingStrategy()
- : state_provider_(nullptr), surface_texture_id_(0), media_codec_(nullptr) {}
+AndroidCopyingBackingStrategy::AndroidCopyingBackingStrategy(
+ AVDAStateProvider* state_provider)
+ : state_provider_(state_provider),
+ surface_texture_id_(0),
+ media_codec_(nullptr) {}
AndroidCopyingBackingStrategy::~AndroidCopyingBackingStrategy() {}
-void AndroidCopyingBackingStrategy::Initialize(
- AVDAStateProvider* state_provider) {
- state_provider_ = state_provider;
+gfx::ScopedJavaSurface AndroidCopyingBackingStrategy::Initialize(
+ int surface_view_id) {
+ if (surface_view_id != media::VideoDecodeAccelerator::Config::kNoSurfaceID) {
+ LOG(ERROR) << "The copying strategy should not be initialized with a "
+ "surface id.";
+ return gfx::ScopedJavaSurface();
+ }
+
+ // Create a texture and attach the SurfaceTexture to it.
+ glGenTextures(1, &surface_texture_id_);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, surface_texture_id_);
+
+ // Note that the target will be correctly sized, so nearest filtering is all
+ // that's needed.
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ state_provider_->GetGlDecoder()->RestoreTextureUnitBindings(0);
+ state_provider_->GetGlDecoder()->RestoreActiveTexture();
+
+ surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_);
+
+ return gfx::ScopedJavaSurface(surface_texture_.get());
}
void AndroidCopyingBackingStrategy::Cleanup(
bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap&) {
DCHECK(state_provider_->ThreadChecker().CalledOnValidThread());
+
if (copier_)
copier_->Destroy();
@@ -42,26 +66,17 @@ void AndroidCopyingBackingStrategy::Cleanup(
glDeleteTextures(1, &surface_texture_id_);
}
+scoped_refptr<gfx::SurfaceTexture>
+AndroidCopyingBackingStrategy::GetSurfaceTexture() const {
+ return surface_texture_;
+}
+
uint32_t AndroidCopyingBackingStrategy::GetTextureTarget() const {
return GL_TEXTURE_2D;
}
-scoped_refptr<gfx::SurfaceTexture>
-AndroidCopyingBackingStrategy::CreateSurfaceTexture() {
- glGenTextures(1, &surface_texture_id_);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, surface_texture_id_);
-
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- state_provider_->GetGlDecoder()->RestoreTextureUnitBindings(0);
- state_provider_->GetGlDecoder()->RestoreActiveTexture();
-
- surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_);
-
- return surface_texture_;
+gfx::Size AndroidCopyingBackingStrategy::GetPictureBufferSize() const {
+ return state_provider_->GetSize();
}
void AndroidCopyingBackingStrategy::UseCodecBufferForPictureBuffer(
@@ -99,16 +114,19 @@ void AndroidCopyingBackingStrategy::UseCodecBufferForPictureBuffer(
surface_texture_->UpdateTexImage();
}
- float transfrom_matrix[16];
- surface_texture_->GetTransformMatrix(transfrom_matrix);
+ float transform_matrix[16];
+ surface_texture_->GetTransformMatrix(transform_matrix);
- uint32_t picture_buffer_texture_id = picture_buffer.texture_id();
+ DCHECK_LE(1u, picture_buffer.texture_ids().size());
+ uint32_t picture_buffer_texture_id = picture_buffer.texture_ids()[0];
// Defer initializing the CopyTextureCHROMIUMResourceManager until it is
// needed because it takes 10s of milliseconds to initialize.
if (!copier_) {
copier_.reset(new gpu::CopyTextureCHROMIUMResourceManager());
- copier_->Initialize(state_provider_->GetGlDecoder().get());
+ copier_->Initialize(state_provider_->GetGlDecoder().get(),
+ state_provider_->GetGlDecoder()->GetContextGroup()->
+ feature_info()->feature_flags());
}
// Here, we copy |surface_texture_id_| to the picture buffer instead of
@@ -118,13 +136,11 @@ void AndroidCopyingBackingStrategy::UseCodecBufferForPictureBuffer(
// attached.
// 2. SurfaceTexture requires us to apply a transform matrix when we show
// the texture.
- // TODO(hkuang): get the StreamTexture transform matrix in GPU process
- // instead of using default matrix crbug.com/226218.
copier_->DoCopyTextureWithTransform(
state_provider_->GetGlDecoder().get(), GL_TEXTURE_EXTERNAL_OES,
surface_texture_id_, GL_TEXTURE_2D, picture_buffer_texture_id,
state_provider_->GetSize().width(), state_provider_->GetSize().height(),
- false, false, false, kIdentityMatrix);
+ true, false, false, transform_matrix);
}
void AndroidCopyingBackingStrategy::CodecChanged(
@@ -140,4 +156,37 @@ void AndroidCopyingBackingStrategy::OnFrameAvailable() {
// instead preserve the old behavior.
}
+bool AndroidCopyingBackingStrategy::ArePicturesOverlayable() {
+ return false;
+}
+
+void AndroidCopyingBackingStrategy::UpdatePictureBufferSize(
+ media::PictureBuffer* picture_buffer,
+ const gfx::Size& new_size) {
+ // This strategy uses 2D textures who's allocated memory is dependent on the
+ // size. To update size in all places, we must:
+ // 1) Update the PictureBuffer meta-data
+ picture_buffer->set_size(new_size);
+
+ // 2) Update the GL texture via glTexImage2D. This step assumes the caller
+ // has made our GL context current.
+ DCHECK_LE(1u, picture_buffer->texture_ids().size());
+ glBindTexture(GL_TEXTURE_2D, picture_buffer->texture_ids()[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, new_size.width(), new_size.height(),
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ state_provider_->GetGlDecoder()->RestoreActiveTextureUnitBinding(
+ GL_TEXTURE_2D);
+
+ // 3) Update the CHROMIUM Texture's size.
+ gpu::gles2::TextureRef* texture_ref =
+ state_provider_->GetTextureForPicture(*picture_buffer);
+ RETURN_IF_NULL(texture_ref);
+ gpu::gles2::TextureManager* texture_manager =
+ state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
+ RETURN_IF_NULL(texture_manager);
+ texture_manager->SetLevelInfo(texture_ref, GetTextureTarget(), 0, GL_RGBA,
+ new_size.width(), new_size.height(), 1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(new_size));
+}
+
} // namespace content
diff --git a/chromium/content/common/gpu/media/android_copying_backing_strategy.h b/chromium/content/common/gpu/media/android_copying_backing_strategy.h
index 17b096aecd5..8980404dfdb 100644
--- a/chromium/content/common/gpu/media/android_copying_backing_strategy.h
+++ b/chromium/content/common/gpu/media/android_copying_backing_strategy.h
@@ -28,21 +28,25 @@ class AVDAStateProvider;
class CONTENT_EXPORT AndroidCopyingBackingStrategy
: public AndroidVideoDecodeAccelerator::BackingStrategy {
public:
- AndroidCopyingBackingStrategy();
+ explicit AndroidCopyingBackingStrategy(AVDAStateProvider* state_provider);
~AndroidCopyingBackingStrategy() override;
// AndroidVideoDecodeAccelerator::BackingStrategy
- void Initialize(AVDAStateProvider*) override;
+ gfx::ScopedJavaSurface Initialize(int surface_view_id) override;
void Cleanup(bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap&) override;
+ scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture() const override;
uint32_t GetTextureTarget() const override;
- scoped_refptr<gfx::SurfaceTexture> CreateSurfaceTexture() override;
+ gfx::Size GetPictureBufferSize() const override;
void UseCodecBufferForPictureBuffer(int32_t codec_buffer_index,
const media::PictureBuffer&) override;
void CodecChanged(
media::VideoCodecBridge*,
const AndroidVideoDecodeAccelerator::OutputBufferMap&) override;
void OnFrameAvailable() override;
+ bool ArePicturesOverlayable() override;
+ void UpdatePictureBufferSize(media::PictureBuffer* picture_buffer,
+ const gfx::Size& new_size) override;
private:
// Used for copy the texture from surface texture to picture buffers.
diff --git a/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc b/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
index 660785eea90..3e62629745d 100644
--- a/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
+++ b/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
@@ -4,30 +4,41 @@
#include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "base/android/build_info.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
-#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/media/avda_codec_image.h"
#include "content/common/gpu/media/avda_return_on_failure.h"
#include "content/common/gpu/media/avda_shared_state.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/gl_stream_texture_image.h"
+#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/ipc/common/gpu_surface_lookup.h"
+#include "gpu/ipc/service/gpu_channel.h"
#include "ui/gl/android/surface_texture.h"
+#include "ui/gl/egl_util.h"
#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/scoped_binders.h"
+#include "ui/gl/scoped_make_current.h"
namespace content {
AndroidDeferredRenderingBackingStrategy::
- AndroidDeferredRenderingBackingStrategy()
- : state_provider_(nullptr), media_codec_(nullptr) {}
+ AndroidDeferredRenderingBackingStrategy(AVDAStateProvider* state_provider)
+ : state_provider_(state_provider), media_codec_(nullptr) {}
AndroidDeferredRenderingBackingStrategy::
~AndroidDeferredRenderingBackingStrategy() {}
-void AndroidDeferredRenderingBackingStrategy::Initialize(
- AVDAStateProvider* state_provider) {
- state_provider_ = state_provider;
+gfx::ScopedJavaSurface AndroidDeferredRenderingBackingStrategy::Initialize(
+ int surface_view_id) {
shared_state_ = new AVDASharedState();
// Create a texture for the SurfaceTexture to use. We don't attach it here
@@ -36,6 +47,27 @@ void AndroidDeferredRenderingBackingStrategy::Initialize(
glGenTextures(1, &service_id);
DCHECK(service_id);
shared_state_->set_surface_texture_service_id(service_id);
+
+ gfx::ScopedJavaSurface surface;
+ if (surface_view_id != media::VideoDecodeAccelerator::Config::kNoSurfaceID) {
+ surface = gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(
+ surface_view_id);
+ } else {
+ if (DoesSurfaceTextureDetachWork()) {
+ // Create a detached SurfaceTexture. Detaching it will silently fail to
+ // delete texture 0.
+ surface_texture_ = gfx::SurfaceTexture::Create(0);
+ surface_texture_->DetachFromGLContext();
+ } else {
+ // Detach doesn't work so well on all platforms. Just attach the
+ // SurfaceTexture here, and probably context switch later.
+ surface_texture_ = gfx::SurfaceTexture::Create(service_id);
+ shared_state_->DidAttachSurfaceTexture();
+ }
+ surface = gfx::ScopedJavaSurface(surface_texture_.get());
+ }
+
+ return surface;
}
void AndroidDeferredRenderingBackingStrategy::Cleanup(
@@ -50,6 +82,11 @@ void AndroidDeferredRenderingBackingStrategy::Cleanup(
for (const std::pair<int, media::PictureBuffer>& entry : buffers)
SetImageForPicture(entry.second, nullptr);
+ // If we're rendering to a SurfaceTexture we can make a copy of the current
+ // front buffer so that the PictureBuffer textures are still valid.
+ if (surface_texture_ && have_context && ShouldCopyPictures())
+ CopySurfaceTextureToPictures(buffers);
+
// Now that no AVDACodecImages refer to the SurfaceTexture's texture, delete
// the texture name.
GLuint service_id = shared_state_->surface_texture_service_id();
@@ -57,38 +94,35 @@ void AndroidDeferredRenderingBackingStrategy::Cleanup(
glDeleteTextures(1, &service_id);
}
-uint32_t AndroidDeferredRenderingBackingStrategy::GetTextureTarget() const {
- return GL_TEXTURE_EXTERNAL_OES;
-}
-
scoped_refptr<gfx::SurfaceTexture>
-AndroidDeferredRenderingBackingStrategy::CreateSurfaceTexture() {
- // AVDACodecImage will handle attaching this to a texture later.
- surface_texture_ = gfx::SurfaceTexture::Create(0);
- // Detach from our GL context so that the GLImages can attach. It will
- // silently fail to delete texture 0.
- surface_texture_->DetachFromGLContext();
-
+AndroidDeferredRenderingBackingStrategy::GetSurfaceTexture() const {
return surface_texture_;
}
-gpu::gles2::TextureRef*
-AndroidDeferredRenderingBackingStrategy::GetTextureForPicture(
- const media::PictureBuffer& picture_buffer) {
- RETURN_NULL_IF_NULL(state_provider_->GetGlDecoder());
- gpu::gles2::TextureManager* texture_manager =
- state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
- RETURN_NULL_IF_NULL(texture_manager);
- gpu::gles2::TextureRef* texture_ref =
- texture_manager->GetTexture(picture_buffer.internal_texture_id());
- RETURN_NULL_IF_NULL(texture_ref);
+uint32_t AndroidDeferredRenderingBackingStrategy::GetTextureTarget() const {
+ // If we're using a surface texture, then we need an external texture target
+ // to sample from it. If not, then we'll use 2D transparent textures to draw
+ // a transparent hole through which to see the SurfaceView. This is normally
+ // needed only for the devtools inspector, since the overlay mechanism handles
+ // it otherwise.
+ return surface_texture_ ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
+}
- return texture_ref;
+gfx::Size AndroidDeferredRenderingBackingStrategy::GetPictureBufferSize()
+ const {
+ // For SurfaceView, request a 1x1 2D texture to reduce memory during
+ // initialization. For SurfaceTexture, allocate a picture buffer that is the
+ // actual frame size. Note that it will be an external texture anyway, so it
+ // doesn't allocate an image of that size. However, it's still important to
+ // get the coded size right, so that VideoLayerImpl doesn't try to scale the
+ // texture when building the quad for it.
+ return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1);
}
AVDACodecImage* AndroidDeferredRenderingBackingStrategy::GetImageForPicture(
const media::PictureBuffer& picture_buffer) {
- gpu::gles2::TextureRef* texture_ref = GetTextureForPicture(picture_buffer);
+ gpu::gles2::TextureRef* texture_ref =
+ state_provider_->GetTextureForPicture(picture_buffer);
RETURN_NULL_IF_NULL(texture_ref);
gl::GLImage* image =
texture_ref->texture()->GetLevelImage(GetTextureTarget(), 0);
@@ -97,8 +131,9 @@ AVDACodecImage* AndroidDeferredRenderingBackingStrategy::GetImageForPicture(
void AndroidDeferredRenderingBackingStrategy::SetImageForPicture(
const media::PictureBuffer& picture_buffer,
- const scoped_refptr<gl::GLImage>& image) {
- gpu::gles2::TextureRef* texture_ref = GetTextureForPicture(picture_buffer);
+ const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image) {
+ gpu::gles2::TextureRef* texture_ref =
+ state_provider_->GetTextureForPicture(picture_buffer);
RETURN_IF_NULL(texture_ref);
gpu::gles2::TextureManager* texture_manager =
@@ -120,15 +155,25 @@ void AndroidDeferredRenderingBackingStrategy::SetImageForPicture(
shared_state_->surface_texture_service_id());
static_cast<AVDACodecImage*>(image.get())
- ->setTexture(texture_ref->texture());
+ ->SetTexture(texture_ref->texture());
} else {
// Clear the unowned service_id, so that this texture is no longer going
// to depend on the surface texture at all.
texture_ref->texture()->SetUnownedServiceId(0);
}
- texture_manager->SetLevelImage(texture_ref, GetTextureTarget(), 0,
- image.get(), gpu::gles2::Texture::UNBOUND);
+ // For SurfaceTexture we set the image to UNBOUND so that the implementation
+ // will call CopyTexImage, which is where AVDACodecImage updates the
+ // SurfaceTexture to the right frame.
+ // For SurfaceView we set the image to be BOUND because ScheduleOverlayPlane
+ // expects it. If something tries to sample from this texture it won't work,
+ // but there's no way to sample from a SurfaceView anyway, so it doesn't
+ // matter. The only way to use this texture is to schedule it as an overlay.
+ const gpu::gles2::Texture::ImageState image_state =
+ surface_texture_ ? gpu::gles2::Texture::UNBOUND
+ : gpu::gles2::Texture::BOUND;
+ texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(),
+ 0, image.get(), image_state);
}
void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
@@ -139,36 +184,53 @@ void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
// Notify the AVDACodecImage for picture_buffer that it should use the
// decoded buffer codec_buf_index to render this frame.
- AVDACodecImage* avImage = GetImageForPicture(picture_buffer);
- RETURN_IF_NULL(avImage);
- DCHECK_EQ(avImage->GetMediaCodecBufferIndex(), -1);
+ AVDACodecImage* avda_image = GetImageForPicture(picture_buffer);
+ RETURN_IF_NULL(avda_image);
+ DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1);
// Note that this is not a race, since we do not re-use a PictureBuffer
// until after the CC is done drawing it.
- avImage->SetMediaCodecBufferIndex(codec_buf_index);
- avImage->SetSize(state_provider_->GetSize());
+ avda_image->SetMediaCodecBufferIndex(codec_buf_index);
+ avda_image->SetSize(state_provider_->GetSize());
}
void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer(
- const media::PictureBuffer& picture_buffer) {
+ const media::PictureBuffer& picture_buffer,
+ bool have_context) {
// Attach a GLImage to each texture that will use the surface texture.
// We use a refptr here in case SetImageForPicture fails.
- scoped_refptr<gl::GLImage> gl_image(
+ scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image =
new AVDACodecImage(shared_state_, media_codec_,
- state_provider_->GetGlDecoder(), surface_texture_));
+ state_provider_->GetGlDecoder(), surface_texture_);
SetImageForPicture(picture_buffer, gl_image);
+
+ if (!surface_texture_ && have_context) {
+ // To make devtools work, we're using a 2D texture. Make it transparent,
+ // so that it draws a hole for the SV to show through. This is only
+ // because devtools draws and reads back, which skips overlay processing.
+ // It's unclear why devtools renders twice -- once normally, and once
+ // including a readback layer. The result is that the device screen
+ // flashes as we alternately draw the overlay hole and this texture,
+ // unless we make the texture transparent.
+ static const uint8_t rgba[] = {0, 0, 0, 0};
+ const gfx::Size size(1, 1);
+ DCHECK_LE(1u, picture_buffer.texture_ids().size());
+ glBindTexture(GL_TEXTURE_2D, picture_buffer.texture_ids()[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, rgba);
+ }
}
void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture(
const media::PictureBuffer& picture_buffer) {
- AVDACodecImage* avImage = GetImageForPicture(picture_buffer);
+ AVDACodecImage* avda_image = GetImageForPicture(picture_buffer);
// See if there is a media codec buffer still attached to this image.
- const int32_t codec_buffer = avImage->GetMediaCodecBufferIndex();
+ const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex();
if (codec_buffer >= 0) {
// PictureBuffer wasn't displayed, so release the buffer.
media_codec_->ReleaseOutputBuffer(codec_buffer, false);
- avImage->SetMediaCodecBufferIndex(-1);
+ avda_image->SetMediaCodecBufferIndex(-1);
}
}
@@ -181,18 +243,6 @@ void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer(
ReleaseCodecBufferForPicture(picture_buffer);
}
-void AndroidDeferredRenderingBackingStrategy::DismissOnePictureBuffer(
- const media::PictureBuffer& picture_buffer) {
- // If there is an outstanding codec buffer attached to this image, then
- // release it.
- ReleaseCodecBufferForPicture(picture_buffer);
-
- // This makes sure that the Texture no longer refers to the codec or to the
- // SurfaceTexture's service_id. That's important, so that it doesn't refer
- // to the texture by name after we've deleted it.
- SetImageForPicture(picture_buffer, nullptr);
-}
-
void AndroidDeferredRenderingBackingStrategy::CodecChanged(
media::VideoCodecBridge* codec,
const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
@@ -200,9 +250,9 @@ void AndroidDeferredRenderingBackingStrategy::CodecChanged(
// doesn't know about them.
media_codec_ = codec;
for (const std::pair<int, media::PictureBuffer>& entry : buffers) {
- AVDACodecImage* avImage = GetImageForPicture(entry.second);
- avImage->SetMediaCodec(codec);
- avImage->SetMediaCodecBufferIndex(-1);
+ AVDACodecImage* avda_image = GetImageForPicture(entry.second);
+ avda_image->SetMediaCodec(codec);
+ avda_image->SetMediaCodecBufferIndex(-1);
}
}
@@ -210,4 +260,163 @@ void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() {
shared_state_->SignalFrameAvailable();
}
+bool AndroidDeferredRenderingBackingStrategy::ArePicturesOverlayable() {
+ // SurfaceView frames are always overlayable because that's the only way to
+ // display them.
+ return !surface_texture_;
+}
+
+void AndroidDeferredRenderingBackingStrategy::UpdatePictureBufferSize(
+ media::PictureBuffer* picture_buffer,
+ const gfx::Size& new_size) {
+ // This strategy uses EGL images which manage the texture size for us. We
+ // simply update the PictureBuffer meta-data and leave the texture as-is.
+ picture_buffer->set_size(new_size);
+}
+
+void AndroidDeferredRenderingBackingStrategy::CopySurfaceTextureToPictures(
+ const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
+ DVLOG(3) << __FUNCTION__;
+
+ // Don't try to copy if the SurfaceTexture was never attached because that
+ // means it was never updated.
+ if (!shared_state_->surface_texture_is_attached())
+ return;
+
+ gpu::gles2::GLES2Decoder* gl_decoder = state_provider_->GetGlDecoder().get();
+ if (!gl_decoder)
+ return;
+
+ const gfx::Size size = state_provider_->GetSize();
+
+ // Create a 2D texture to hold a copy of the SurfaceTexture's front buffer.
+ GLuint tmp_texture_id;
+ glGenTextures(1, &tmp_texture_id);
+ {
+ gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, tmp_texture_id);
+ // The target texture's size will exactly match the source.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ }
+
+
+
+ float transform_matrix[16];
+ surface_texture_->GetTransformMatrix(transform_matrix);
+
+ gpu::CopyTextureCHROMIUMResourceManager copier;
+ copier.Initialize(
+ gl_decoder,
+ gl_decoder->GetContextGroup()->feature_info()->feature_flags());
+ copier.DoCopyTextureWithTransform(gl_decoder, GL_TEXTURE_EXTERNAL_OES,
+ shared_state_->surface_texture_service_id(),
+ GL_TEXTURE_2D, tmp_texture_id, size.width(),
+ size.height(), true, false, false,
+ transform_matrix);
+
+ // Create an EGLImage from the 2D texture we just copied into. By associating
+ // the EGLImage with the PictureBuffer textures they will remain valid even
+ // after we delete the 2D texture and EGLImage.
+ const EGLImageKHR egl_image = eglCreateImageKHR(
+ gfx::GLSurfaceEGL::GetHardwareDisplay(), eglGetCurrentContext(),
+ EGL_GL_TEXTURE_2D_KHR, reinterpret_cast<EGLClientBuffer>(tmp_texture_id),
+ nullptr /* attrs */);
+
+ glDeleteTextures(1, &tmp_texture_id);
+ DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+
+ if (egl_image == EGL_NO_IMAGE_KHR) {
+ DLOG(ERROR) << "Failed creating EGLImage: " << ui::GetLastEGLErrorString();
+ return;
+ }
+
+ for (const std::pair<int, media::PictureBuffer>& entry : buffers) {
+ gpu::gles2::TextureRef* texture_ref =
+ state_provider_->GetTextureForPicture(entry.second);
+ if (!texture_ref)
+ continue;
+ gfx::ScopedTextureBinder texture_binder(
+ GL_TEXTURE_EXTERNAL_OES, texture_ref->texture()->service_id());
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
+ DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ }
+
+ EGLBoolean result =
+ eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), egl_image);
+ if (result == EGL_FALSE) {
+ DLOG(ERROR) << "Error destroying EGLImage: "
+ << ui::GetLastEGLErrorString();
+ }
+}
+
+bool AndroidDeferredRenderingBackingStrategy::DoesSurfaceTextureDetachWork()
+ const {
+ bool surface_texture_detach_works = true;
+ if (gpu::gles2::GLES2Decoder* gl_decoder =
+ state_provider_->GetGlDecoder().get()) {
+ if (gpu::gles2::ContextGroup* group = gl_decoder->GetContextGroup()) {
+ if (gpu::gles2::FeatureInfo* feature_info = group->feature_info()) {
+ surface_texture_detach_works =
+ !feature_info->workarounds().surface_texture_cant_detach;
+ }
+ }
+ }
+
+ // As a special case, the MicroMax A114 doesn't get the workaround, even
+ // though it should. Hardcode it here until we get a device and figure out
+ // why. crbug.com/591600
+ if (base::android::BuildInfo::GetInstance()->sdk_int() <= 18) { // JB
+ const std::string brand(
+ base::ToLowerASCII(base::android::BuildInfo::GetInstance()->brand()));
+ if (brand == "micromax") {
+ const std::string model(
+ base::ToLowerASCII(base::android::BuildInfo::GetInstance()->model()));
+ if (model.find("a114") != std::string::npos)
+ surface_texture_detach_works = false;
+ }
+ }
+
+ return surface_texture_detach_works;
+}
+
+bool AndroidDeferredRenderingBackingStrategy::ShouldCopyPictures() const {
+ // Mali + <= KitKat crashes when we try to do this. We don't know if it's
+ // due to detaching a surface texture, but it's the same set of devices.
+ if (!DoesSurfaceTextureDetachWork())
+ return false;
+
+ // Other devices are unreliable for other reasons (e.g., EGLImage).
+ if (gpu::gles2::GLES2Decoder* gl_decoder =
+ state_provider_->GetGlDecoder().get()) {
+ if (gpu::gles2::ContextGroup* group = gl_decoder->GetContextGroup()) {
+ if (gpu::gles2::FeatureInfo* feature_info = group->feature_info()) {
+ return !feature_info->workarounds().avda_dont_copy_pictures;
+ }
+ }
+ }
+
+ // Samsung Galaxy Tab A, J3, and J1 Mini all like to crash on Lollipop in
+ // glEGLImageTargetTexture2DOES . Exact models were SM-T280, SM-J320F,
+ // and SM-j105H.
+ if (base::android::BuildInfo::GetInstance()->sdk_int() <= 22) { // L MR1
+ const std::string brand(
+ base::ToLowerASCII(base::android::BuildInfo::GetInstance()->brand()));
+ if (brand == "samsung") {
+ const std::string model(
+ base::ToLowerASCII(base::android::BuildInfo::GetInstance()->model()));
+ if (model.find("sm-t280") != std::string::npos ||
+ model.find("sm-j320f") != std::string::npos ||
+ model.find("sm-j105") != std::string::npos)
+ return false;
+ }
+ }
+
+ // Assume so.
+ return true;
+}
+
} // namespace content
diff --git a/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.h b/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.h
index 6fc1873cf5a..733b25b0a45 100644
--- a/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.h
+++ b/chromium/content/common/gpu/media/android_deferred_rendering_backing_strategy.h
@@ -17,6 +17,7 @@ class GLImage;
namespace gpu {
namespace gles2 {
+class GLStreamTextureImage;
class TextureRef;
}
}
@@ -33,42 +34,61 @@ class AVDASharedState;
class CONTENT_EXPORT AndroidDeferredRenderingBackingStrategy
: public AndroidVideoDecodeAccelerator::BackingStrategy {
public:
- AndroidDeferredRenderingBackingStrategy();
+ explicit AndroidDeferredRenderingBackingStrategy(
+ AVDAStateProvider* state_provider);
~AndroidDeferredRenderingBackingStrategy() override;
// AndroidVideoDecodeAccelerator::BackingStrategy
- void Initialize(AVDAStateProvider*) override;
+ gfx::ScopedJavaSurface Initialize(int surface_view_id) override;
void Cleanup(bool have_context,
const AndroidVideoDecodeAccelerator::OutputBufferMap&) override;
+ scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture() const override;
uint32_t GetTextureTarget() const override;
- scoped_refptr<gfx::SurfaceTexture> CreateSurfaceTexture() override;
+ gfx::Size GetPictureBufferSize() const override;
void UseCodecBufferForPictureBuffer(int32_t codec_buffer_index,
const media::PictureBuffer&) override;
- void AssignOnePictureBuffer(const media::PictureBuffer&) override;
+ void AssignOnePictureBuffer(const media::PictureBuffer&, bool) override;
void ReuseOnePictureBuffer(const media::PictureBuffer&) override;
- void DismissOnePictureBuffer(const media::PictureBuffer&) override;
void CodecChanged(
media::VideoCodecBridge*,
const AndroidVideoDecodeAccelerator::OutputBufferMap&) override;
void OnFrameAvailable() override;
+ bool ArePicturesOverlayable() override;
+ void UpdatePictureBufferSize(media::PictureBuffer* picture_buffer,
+ const gfx::Size& new_size) override;
private:
// Release any codec buffer that is associated with the given picture buffer
// back to the codec. It is okay if there is no such buffer.
void ReleaseCodecBufferForPicture(const media::PictureBuffer& picture_buffer);
- // Return the TextureRef for a given PictureBuffer's texture.
- gpu::gles2::TextureRef* GetTextureForPicture(const media::PictureBuffer&);
-
// Return the AVDACodecImage for a given PictureBuffer's texture.
AVDACodecImage* GetImageForPicture(const media::PictureBuffer&);
- void SetImageForPicture(const media::PictureBuffer& picture_buffer,
- const scoped_refptr<gl::GLImage>& image);
+ void SetImageForPicture(
+ const media::PictureBuffer& picture_buffer,
+ const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image);
+
+ // Make a copy of the SurfaceTexture's front buffer and associate all given
+ // picture buffer textures with it. The picture buffer textures will not
+ // dependend on |this|, the SurfaceTexture, the MediaCodec or the VDA, so it's
+ // used to back the picture buffers when the VDA is being destroyed.
+ void CopySurfaceTextureToPictures(
+ const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers);
+
+ // Return true if and only if the surface_texture_cant_detach workaround is
+ // not set.
+ bool DoesSurfaceTextureDetachWork() const;
+
+ // Return true if and only if CopySurfaceTextureToPictures is expected to work
+ // on this device.
+ bool ShouldCopyPictures() const;
scoped_refptr<AVDASharedState> shared_state_;
AVDAStateProvider* state_provider_;
+ // The SurfaceTexture to render to. Non-null after Initialize() if
+ // we're not rendering to a SurfaceView.
scoped_refptr<gfx::SurfaceTexture> surface_texture_;
media::VideoCodecBridge* media_codec_;
diff --git a/chromium/content/common/gpu/media/android_video_decode_accelerator.cc b/chromium/content/common/gpu/media/android_video_decode_accelerator.cc
index 832d8dca218..e4f45ca73b3 100644
--- a/chromium/content/common/gpu/media/android_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -7,21 +7,30 @@
#include <stddef.h>
#include "base/android/build_info.h"
+#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/task_runner_util.h"
+#include "base/threading/thread_checker.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/media/android_copying_backing_strategy.h"
#include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h"
+#include "content/common/gpu/media/avda_return_on_failure.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/ipc/service/gpu_channel.h"
+#include "media/base/android/media_codec_bridge.h"
+#include "media/base/android/media_codec_util.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/limits.h"
-#include "media/base/media_switches.h"
+#include "media/base/media.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_decoder_config.h"
#include "media/video/picture.h"
@@ -30,7 +39,6 @@
#include "ui/gl/gl_bindings.h"
#if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
-#include "media/base/media_keys.h"
#include "media/mojo/services/mojo_cdm_service.h"
#endif
@@ -92,6 +100,23 @@ static inline const base::TimeDelta IdleTimerTimeOut() {
return base::TimeDelta::FromSeconds(1);
}
+// Time between when we notice an error, and when we actually notify somebody.
+// This is to prevent codec errors caused by SurfaceView fullscreen transitions
+// from breaking the pipeline, if we're about to be reset anyway.
+static inline const base::TimeDelta ErrorPostingDelay() {
+ return base::TimeDelta::FromSeconds(2);
+}
+
+// For RecordFormatChangedMetric.
+enum FormatChangedValue {
+ CodecInitialized = false,
+ MissingFormatChanged = true
+};
+
+static inline void RecordFormatChangedMetric(FormatChangedValue value) {
+ UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value);
+}
+
// Handle OnFrameAvailable callbacks safely. Since they occur asynchronously,
// we take care that the AVDA that wants them still exists. A WeakPtr to
// the AVDA would be preferable, except that OnFrameAvailable callbacks can
@@ -143,34 +168,166 @@ class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler
DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
};
+// Helper class to share an IO timer for DoIOTask() execution; prevents each
+// AVDA instance from starting its own high frequency timer. The intuition
+// behind this is that, if we're waiting for long enough, then either (a)
+// MediaCodec is broken or (b) MediaCodec is waiting on us to change state
+// (e.g., get new demuxed data / get a free picture buffer / return an output
+// buffer to MediaCodec). This is inherently a race, since we don't know if
+// MediaCodec is broken or just slow. Since the MediaCodec API doesn't let
+// us wait on MediaCodec state changes prior to L, we more or less have to
+// time out or keep polling forever in some common cases.
+class AVDATimerManager {
+ public:
+ // Make sure that the construction thread is started for |avda_instance|.
+ bool StartThread(AndroidVideoDecodeAccelerator* avda_instance) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (thread_avda_instances_.empty()) {
+ if (!construction_thread_.Start()) {
+ LOG(ERROR) << "Failed to start construction thread.";
+ return false;
+ }
+ }
+
+ thread_avda_instances_.insert(avda_instance);
+ return true;
+ }
+
+ // |avda_instance| will no longer need the construction thread. Stop the
+ // thread if this is the last instance.
+ void StopThread(AndroidVideoDecodeAccelerator* avda_instance) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ thread_avda_instances_.erase(avda_instance);
+ if (thread_avda_instances_.empty())
+ construction_thread_.Stop();
+ }
+
+ // Request periodic callback of |avda_instance|->DoIOTask(). Does nothing if
+ // the instance is already registered and the timer started. The first request
+ // will start the repeating timer on an interval of DecodePollDelay().
+ void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ timer_avda_instances_.insert(avda_instance);
+
+ // If the timer is running, StopTimer() might have been called earlier, if
+ // so remove the instance from the pending erasures.
+ if (timer_running_)
+ pending_erase_.erase(avda_instance);
+
+ if (io_timer_.IsRunning())
+ return;
+ io_timer_.Start(FROM_HERE, DecodePollDelay(), this,
+ &AVDATimerManager::RunTimer);
+ }
+
+ // Stop callbacks to |avda_instance|->DoIOTask(). Does nothing if the instance
+ // is not registered. If there are no instances left, the repeating timer will
+ // be stopped.
+ void StopTimer(AndroidVideoDecodeAccelerator* avda_instance) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // If the timer is running, defer erasures to avoid iterator invalidation.
+ if (timer_running_) {
+ pending_erase_.insert(avda_instance);
+ return;
+ }
+
+ timer_avda_instances_.erase(avda_instance);
+ if (timer_avda_instances_.empty())
+ io_timer_.Stop();
+ }
+
+ // Eventually, we should run the timer on this thread. For now, we just keep
+ // it as a convenience for construction.
+ scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return construction_thread_.task_runner();
+ }
+
+ private:
+ friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>;
+
+ AVDATimerManager() : construction_thread_("AVDAThread") {}
+ ~AVDATimerManager() { NOTREACHED(); }
+
+ void RunTimer() {
+ {
+ // Call out to all AVDA instances, some of which may attempt to remove
+ // themselves from the list during this operation; those removals will be
+ // deferred until after all iterations are complete.
+ base::AutoReset<bool> scoper(&timer_running_, true);
+ for (auto* avda : timer_avda_instances_)
+ avda->DoIOTask(false);
+ }
+
+ // Take care of any deferred erasures.
+ for (auto* avda : pending_erase_)
+ StopTimer(avda);
+ pending_erase_.clear();
+
+ // TODO(dalecurtis): We may want to consider chunking this if task execution
+ // takes too long for the combined timer.
+ }
+
+ // All AVDA instances that would like us to poll DoIOTask.
+ std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_;
+
+ // All AVDA instances that might like to use the construction thread.
+ std::set<AndroidVideoDecodeAccelerator*> thread_avda_instances_;
+
+ // Since we can't delete while iterating when using a set, defer erasure until
+ // after iteration complete.
+ bool timer_running_ = false;
+ std::set<AndroidVideoDecodeAccelerator*> pending_erase_;
+
+ // Repeating timer responsible for draining pending IO to the codecs.
+ base::RepeatingTimer io_timer_;
+
+ base::Thread construction_thread_;
+
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(AVDATimerManager);
+};
+
+static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer =
+ LAZY_INSTANCE_INITIALIZER;
+
+AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {}
+
+AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {}
+
AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
- const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder,
- const base::Callback<bool(void)>& make_context_current)
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb)
: client_(NULL),
- make_context_current_(make_context_current),
- codec_(media::kCodecH264),
+ make_context_current_cb_(make_context_current_cb),
+ get_gles2_decoder_cb_(get_gles2_decoder_cb),
is_encrypted_(false),
- needs_protected_surface_(false),
state_(NO_ERROR),
picturebuffers_requested_(false),
- gl_decoder_(decoder),
+ media_drm_bridge_cdm_context_(nullptr),
cdm_registration_id_(0),
- weak_this_factory_(this) {
- if (UseDeferredRenderingStrategy())
- strategy_.reset(new AndroidDeferredRenderingBackingStrategy());
- else
- strategy_.reset(new AndroidCopyingBackingStrategy());
-}
+ pending_input_buf_index_(-1),
+ error_sequence_token_(0),
+ defer_errors_(false),
+ deferred_initialization_pending_(false),
+ weak_this_factory_(this) {}
AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
DCHECK(thread_checker_.CalledOnValidThread());
+ g_avda_timer.Pointer()->StopTimer(this);
+ g_avda_timer.Pointer()->StopThread(this);
#if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
- if (cdm_) {
- DCHECK(cdm_registration_id_);
- static_cast<media::MediaDrmBridge*>(cdm_.get())
- ->UnregisterPlayer(cdm_registration_id_);
- }
+ if (!media_drm_bridge_cdm_context_)
+ return;
+
+ DCHECK(cdm_registration_id_);
+ media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_);
#endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
}
@@ -182,76 +339,130 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
+ if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
DCHECK(client);
client_ = client;
- codec_ = VideoCodecProfileToVideoCodec(config.profile);
+ codec_config_ = new CodecConfig();
+ codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile);
+ codec_config_->initial_expected_coded_size_ =
+ config.initial_expected_coded_size;
is_encrypted_ = config.is_encrypted;
- bool profile_supported = codec_ == media::kCodecVP8 ||
- codec_ == media::kCodecVP9 ||
- codec_ == media::kCodecH264;
+ bool profile_supported = codec_config_->codec_ == media::kCodecVP8 ||
+ codec_config_->codec_ == media::kCodecVP9 ||
+ codec_config_->codec_ == media::kCodecH264;
+
+ // We signalled that we support deferred initialization, so see if the client
+ // does also.
+ deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
if (!profile_supported) {
LOG(ERROR) << "Unsupported profile: " << config.profile;
return false;
}
+ // For encrypted streams we postpone configuration until MediaCrypto is
+ // available.
+ DCHECK(!is_encrypted_ || deferred_initialization_pending_);
+
// Only use MediaCodec for VP8/9 if it's likely backed by hardware
// or if the stream is encrypted.
- if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) &&
- !is_encrypted_) {
- if (media::VideoCodecBridge::IsKnownUnaccelerated(
- codec_, media::MEDIA_CODEC_DECODER)) {
- DVLOG(1) << "Initialization failed: "
- << (codec_ == media::kCodecVP8 ? "vp8" : "vp9")
- << " is not hardware accelerated";
- return false;
- }
+ if ((codec_config_->codec_ == media::kCodecVP8 ||
+ codec_config_->codec_ == media::kCodecVP9) &&
+ !is_encrypted_ &&
+ media::VideoCodecBridge::IsKnownUnaccelerated(
+ codec_config_->codec_, media::MEDIA_CODEC_DECODER)) {
+ DVLOG(1) << "Initialization failed: "
+ << (codec_config_->codec_ == media::kCodecVP8 ? "vp8" : "vp9")
+ << " is not hardware accelerated";
+ return false;
}
- if (!make_context_current_.Run()) {
+ auto gles_decoder = get_gles2_decoder_cb_.Run();
+ if (!gles_decoder) {
+ LOG(ERROR) << "Failed to get gles2 decoder instance.";
+ return false;
+ }
+
+ const gpu::GpuPreferences& gpu_preferences =
+ gles_decoder->GetContextGroup()->gpu_preferences();
+
+ if (UseDeferredRenderingStrategy(gpu_preferences)) {
+ // TODO(liberato, watk): Figure out what we want to do about zero copy for
+ // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
+ DCHECK(!gles_decoder->GetContextGroup()->mailbox_manager()->UsesSync());
+ DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
+ strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
+ } else {
+ DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
+ strategy_.reset(new AndroidCopyingBackingStrategy(this));
+ }
+
+ if (!make_context_current_cb_.Run()) {
LOG(ERROR) << "Failed to make this decoder's GL context current.";
return false;
}
- if (!gl_decoder_) {
- LOG(ERROR) << "Failed to get gles2 decoder instance.";
+ codec_config_->surface_ = strategy_->Initialize(config.surface_id);
+ if (codec_config_->surface_.IsEmpty()) {
+ LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
+ "Java surface is empty.";
return false;
}
- strategy_->Initialize(this);
+ // TODO(watk,liberato): move this into the strategy.
+ scoped_refptr<gfx::SurfaceTexture> surface_texture =
+ strategy_->GetSurfaceTexture();
+ if (surface_texture) {
+ on_frame_available_handler_ =
+ new OnFrameAvailableHandler(this, surface_texture);
+ }
- surface_texture_ = strategy_->CreateSurfaceTexture();
- on_frame_available_handler_ =
- new OnFrameAvailableHandler(this, surface_texture_);
+ // Start the thread for async configuration, even if we don't need it now.
+ // ResetCodecState might rebuild the codec later, for example.
+ if (!g_avda_timer.Pointer()->StartThread(this)) {
+ LOG(ERROR) << "Failed to start thread for AVDA timer";
+ return false;
+ }
- // For encrypted streams we postpone configuration until MediaCrypto is
- // available.
+ // If we are encrypted, then we aren't able to create the codec yet.
if (is_encrypted_)
return true;
- return ConfigureMediaCodec();
+ if (deferred_initialization_pending_) {
+ ConfigureMediaCodecAsynchronously();
+ return true;
+ }
+
+ // If the client doesn't support deferred initialization (WebRTC), then we
+ // should complete it now and return a meaningful result.
+ return ConfigureMediaCodecSynchronously();
}
void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
DVLOG(2) << __FUNCTION__ << ": " << cdm_id;
#if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
- using media::MediaDrmBridge;
-
DCHECK(client_) << "SetCdm() must be called after Initialize().";
- if (cdm_) {
+ if (media_drm_bridge_cdm_context_) {
NOTREACHED() << "We do not support resetting CDM.";
- NotifyCdmAttached(false);
+ NotifyInitializationComplete(false);
return;
}
- cdm_ = media::MojoCdmService::GetCdm(cdm_id);
- DCHECK(cdm_);
+ // Store the CDM to hold a reference to it.
+ cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id);
+ DCHECK(cdm_for_reference_holding_only_);
- // On Android platform the MediaKeys will be its subclass MediaDrmBridge.
- MediaDrmBridge* drm_bridge = static_cast<MediaDrmBridge*>(cdm_.get());
+ // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext.
+ media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>(
+ cdm_for_reference_holding_only_->GetCdmContext());
+ DCHECK(media_drm_bridge_cdm_context_);
// Register CDM callbacks. The callbacks registered will be posted back to
// this thread via BindToCurrentLoop.
@@ -261,31 +472,30 @@ void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
// destructed as well. So the |cdm_unset_cb| will never have a chance to be
// called.
// TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms.
- cdm_registration_id_ =
- drm_bridge->RegisterPlayer(media::BindToCurrentLoop(base::Bind(
- &AndroidVideoDecodeAccelerator::OnKeyAdded,
- weak_this_factory_.GetWeakPtr())),
- base::Bind(&base::DoNothing));
+ cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer(
+ media::BindToCurrentLoop(
+ base::Bind(&AndroidVideoDecodeAccelerator::OnKeyAdded,
+ weak_this_factory_.GetWeakPtr())),
+ base::Bind(&base::DoNothing));
- drm_bridge->SetMediaCryptoReadyCB(media::BindToCurrentLoop(
+ media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(media::BindToCurrentLoop(
base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady,
weak_this_factory_.GetWeakPtr())));
- // Postpone NotifyCdmAttached() call till we create the MediaCodec after
- // OnMediaCryptoReady().
-
+// Postpone NotifyInitializationComplete() call till we create the MediaCodec
+// after OnMediaCryptoReady().
#else
NOTIMPLEMENTED();
- NotifyCdmAttached(false);
+ NotifyInitializationComplete(false);
#endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
}
-void AndroidVideoDecodeAccelerator::DoIOTask() {
+void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("media", "AVDA::DoIOTask");
- if (state_ == ERROR) {
+ if (state_ == ERROR || state_ == WAITING_FOR_CODEC) {
return;
}
@@ -293,49 +503,69 @@ void AndroidVideoDecodeAccelerator::DoIOTask() {
while (DequeueOutput())
did_work = true;
- ManageTimer(did_work);
+ ManageTimer(did_work || start_timer);
}
bool AndroidVideoDecodeAccelerator::QueueInput() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("media", "AVDA::QueueInput");
+ base::AutoReset<bool> auto_reset(&defer_errors_, true);
if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
return false;
if (pending_bitstream_buffers_.empty())
return false;
+ if (state_ == WAITING_FOR_KEY)
+ return false;
- int input_buf_index = 0;
- media::MediaCodecStatus status =
- media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index);
+ int input_buf_index = pending_input_buf_index_;
- if (status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER)
- return false;
- if (status == media::MEDIA_CODEC_ERROR) {
- POST_ERROR(PLATFORM_FAILURE, "Failed to DequeueInputBuffer");
- return false;
+ // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY.
+ // That status does not return this buffer back to the pool of
+ // available input buffers. We have to reuse it in QueueSecureInputBuffer().
+ if (input_buf_index == -1) {
+ media::MediaCodecStatus status =
+ media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index);
+ switch (status) {
+ case media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
+ return false;
+ case media::MEDIA_CODEC_ERROR:
+ POST_ERROR(PLATFORM_FAILURE, "Failed to DequeueInputBuffer");
+ return false;
+ case media::MEDIA_CODEC_OK:
+ break;
+ default:
+ NOTREACHED() << "Unknown DequeueInputBuffer status " << status;
+ return false;
+ }
}
- DCHECK_EQ(status, media::MEDIA_CODEC_OK);
- base::Time queued_time = pending_bitstream_buffers_.front().second;
- UMA_HISTOGRAM_TIMES("Media.AVDA.InputQueueTime",
- base::Time::Now() - queued_time);
- media::BitstreamBuffer bitstream_buffer =
- pending_bitstream_buffers_.front().first;
+ DCHECK_NE(input_buf_index, -1);
+
+ media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front();
if (bitstream_buffer.id() == -1) {
pending_bitstream_buffers_.pop();
TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
pending_bitstream_buffers_.size());
+ DCHECK_NE(state_, ERROR);
+ state_ = WAITING_FOR_EOS;
media_codec_->QueueEOS(input_buf_index);
return true;
}
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(bitstream_buffer.handle(), true));
- if (!shm->Map(bitstream_buffer.size())) {
- POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemory::Map()");
- return false;
+ scoped_ptr<SharedMemoryRegion> shm;
+
+ if (pending_input_buf_index_ == -1) {
+ // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
+ // from MediaCodec, filled with data and bitstream_buffer.handle() is
+ // closed.
+ shm.reset(new SharedMemoryRegion(bitstream_buffer, true));
+
+ if (!shm->Map()) {
+ POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemoryRegion::Map()");
+ return false;
+ }
}
const base::TimeDelta presentation_timestamp =
@@ -351,12 +581,16 @@ bool AndroidVideoDecodeAccelerator::QueueInput() {
// result in them finding the right timestamp.
bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id();
- const uint8_t* memory = static_cast<const uint8_t*>(shm->memory());
+ // Notice that |memory| will be null if we repeatedly enqueue the same buffer,
+ // this happens after MEDIA_CODEC_NO_KEY.
+ const uint8_t* memory =
+ shm ? static_cast<const uint8_t*>(shm->memory()) : nullptr;
const std::string& key_id = bitstream_buffer.key_id();
const std::string& iv = bitstream_buffer.iv();
const std::vector<media::SubsampleEntry>& subsamples =
bitstream_buffer.subsamples();
+ media::MediaCodecStatus status;
if (key_id.empty() || iv.empty()) {
status = media_codec_->QueueInputBuffer(input_buf_index, memory,
bitstream_buffer.size(),
@@ -372,24 +606,18 @@ bool AndroidVideoDecodeAccelerator::QueueInput() {
<< " status:" << status;
if (status == media::MEDIA_CODEC_NO_KEY) {
- // Keep trying to enqueue the front pending buffer.
- //
- // TODO(timav): Figure out whether stopping the pipeline in response to
- // this error and restarting it in OnKeyAdded() has significant benefits
- // (e.g. saving power).
+ // Keep trying to enqueue the same input buffer.
+ // The buffer is owned by us (not the MediaCodec) and is filled with data.
DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY";
- return true;
+ pending_input_buf_index_ = input_buf_index;
+ state_ = WAITING_FOR_KEY;
+ return false;
}
+ pending_input_buf_index_ = -1;
pending_bitstream_buffers_.pop();
TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
pending_bitstream_buffers_.size());
-
- if (status != media::MEDIA_CODEC_OK) {
- POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status);
- return false;
- }
-
// We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
// will be returned from the bitstream buffer. However, MediaCodec API is
// not enough to guarantee it.
@@ -403,12 +631,18 @@ bool AndroidVideoDecodeAccelerator::QueueInput() {
weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
+ if (status != media::MEDIA_CODEC_OK) {
+ POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status);
+ return false;
+ }
+
return true;
}
bool AndroidVideoDecodeAccelerator::DequeueOutput() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("media", "AVDA::DequeueOutput");
+ base::AutoReset<bool> auto_reset(&defer_errors_, true);
if (picturebuffers_requested_ && output_picture_buffers_.empty())
return false;
@@ -432,10 +666,6 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
"presentation_timestamp (ms)",
presentation_timestamp.InMilliseconds());
- DVLOG(3) << "AVDA::DequeueOutput: pts:" << presentation_timestamp
- << " buf_index:" << buf_index << " offset:" << offset
- << " size:" << size << " eos:" << eos;
-
switch (status) {
case media::MEDIA_CODEC_ERROR:
POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
@@ -445,23 +675,30 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
return false;
case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
- if (!output_picture_buffers_.empty()) {
- // TODO(chcunningham): This will likely dismiss a handful of decoded
- // frames that have not yet been drawn and returned to us for re-use.
- // Consider a more complicated design that would wait for them to be
- // drawn before dismissing.
- DismissPictureBuffers();
+ if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
+ POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
+ return false;
+ }
+ DVLOG(3) << __FUNCTION__
+ << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
+
+ // Don't request picture buffers if we already have some. This avoids
+ // having to dismiss the existing buffers which may actively reference
+ // decoded images. Breaking their connection to the decoded image will
+ // cause rendering of black frames. Instead, we let the existing
+ // PictureBuffers live on and we simply update their size the next time
+ // they're attachted to an image of the new resolution. See the
+ // size update in |SendDecodedFrameToClient| and https://crbug/587994.
+ if (output_picture_buffers_.empty() && !picturebuffers_requested_) {
+ picturebuffers_requested_ = true;
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
+ weak_this_factory_.GetWeakPtr()));
+ return false;
}
- picturebuffers_requested_ = true;
- int32_t width, height;
- media_codec_->GetOutputFormat(&width, &height);
- size_ = gfx::Size(width, height);
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
- weak_this_factory_.GetWeakPtr()));
- return false;
+ return true;
}
case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
@@ -469,6 +706,9 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
case media::MEDIA_CODEC_OK:
DCHECK_GE(buf_index, 0);
+ DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
+ << " buf_index:" << buf_index << " offset:" << offset
+ << " size:" << size << " eos:" << eos;
break;
default:
@@ -478,12 +718,36 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
} while (buf_index < 0);
if (eos) {
- DVLOG(3) << "AVDA::DequeueOutput: Resetting codec state after EOS";
+ DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS";
+
+ // If we were waiting for an EOS, clear the state and reset the MediaCodec
+ // as normal. Otherwise, enter the ERROR state which will force destruction
+ // of MediaCodec during ResetCodecState().
+ //
+ // Some Android platforms seem to send an EOS buffer even when we're not
+ // expecting it. In this case, destroy and reset the codec but don't notify
+ // flush done since it violates the state machine. http://crbug.com/585959.
+ const bool was_waiting_for_eos = state_ == WAITING_FOR_EOS;
+ state_ = was_waiting_for_eos ? NO_ERROR : ERROR;
+
ResetCodecState();
+ // |media_codec_| might still be null.
+ if (was_waiting_for_eos) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
+ weak_this_factory_.GetWeakPtr()));
+ }
+ return false;
+ }
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
- weak_this_factory_.GetWeakPtr()));
+ if (!picturebuffers_requested_) {
+ // If, somehow, we get a decoded frame back before a FORMAT_CHANGED
+ // message, then we might not have any picture buffers to use. This
+ // isn't supposed to happen (see EncodeDecodeTest.java#617).
+ // Log a metric to see how common this is.
+ RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged);
+ media_codec_->ReleaseOutputBuffer(buf_index, false);
+ POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
return false;
}
@@ -515,7 +779,7 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
// correction and provides a non-decreasing timestamp sequence, which might
// result in timestamp duplicates. Discard the frame if we cannot get the
// corresponding buffer id.
- DVLOG(3) << "AVDA::DequeueOutput: Releasing buffer with unexpected PTS: "
+ DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: "
<< presentation_timestamp;
media_codec_->ReleaseOutputBuffer(buf_index, false);
}
@@ -532,7 +796,7 @@ void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
DCHECK(!free_picture_ids_.empty());
TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
return;
}
@@ -541,46 +805,71 @@ void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
free_picture_ids_.pop();
TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
- OutputBufferMap::const_iterator i =
- output_picture_buffers_.find(picture_buffer_id);
+ const auto& i = output_picture_buffers_.find(picture_buffer_id);
if (i == output_picture_buffers_.end()) {
POST_ERROR(PLATFORM_FAILURE,
"Can't find PictureBuffer id: " << picture_buffer_id);
return;
}
+ bool size_changed = false;
+ if (i->second.size() != size_) {
+ // Size may have changed due to resolution change since the last time this
+ // PictureBuffer was used.
+ strategy_->UpdatePictureBufferSize(&i->second, size_);
+ size_changed = true;
+ }
+
// Connect the PictureBuffer to the decoded frame, via whatever
// mechanism the strategy likes.
strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
+ const bool allow_overlay = strategy_->ArePicturesOverlayable();
+
+ media::Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_),
+ allow_overlay);
+ picture.set_size_changed(size_changed);
+
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
- weak_this_factory_.GetWeakPtr(),
- media::Picture(picture_buffer_id, bitstream_id,
- gfx::Rect(size_), false)));
+ weak_this_factory_.GetWeakPtr(), picture));
}
void AndroidVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
+
+ if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
+ DecodeBuffer(bitstream_buffer);
+ return;
+ }
+
+ if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
+ base::SharedMemory::CloseHandle(bitstream_buffer.handle());
+
+ if (bitstream_buffer.id() < 0) {
+ POST_ERROR(INVALID_ARGUMENT,
+ "Invalid bistream_buffer, id: " << bitstream_buffer.id());
+ } else {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
- return;
}
+}
- pending_bitstream_buffers_.push(
- std::make_pair(bitstream_buffer, base::Time::Now()));
+void AndroidVideoDecodeAccelerator::DecodeBuffer(
+ const media::BitstreamBuffer& bitstream_buffer) {
+ pending_bitstream_buffers_.push(bitstream_buffer);
TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
pending_bitstream_buffers_.size());
- DoIOTask();
+ DoIOTask(true);
}
void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
- client_->ProvidePictureBuffers(kNumPictureBuffers, size_,
+ client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
+ strategy_->GetPictureBufferSize(),
strategy_->GetTextureTarget());
}
@@ -595,8 +884,12 @@ void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
return;
}
+ const bool have_context = make_context_current_cb_.Run();
+ LOG_IF(WARNING, !have_context)
+ << "Failed to make GL context current for Assign, continuing.";
+
for (size_t i = 0; i < buffers.size(); ++i) {
- if (buffers[i].size() != size_) {
+ if (buffers[i].size() != strategy_->GetPictureBufferSize()) {
POST_ERROR(INVALID_ARGUMENT,
"Invalid picture buffer size assigned. Wanted "
<< size_.ToString() << ", but got "
@@ -606,29 +899,17 @@ void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
int32_t id = buffers[i].id();
output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
free_picture_ids_.push(id);
- // Since the client might be re-using |picture_buffer_id| values, forget
- // about previously-dismissed IDs now. See ReusePictureBuffer() comment
- // about "zombies" for why we maintain this set in the first place.
- dismissed_picture_ids_.erase(id);
- strategy_->AssignOnePictureBuffer(buffers[i]);
+ strategy_->AssignOnePictureBuffer(buffers[i], have_context);
}
TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
-
- DoIOTask();
+ DoIOTask(true);
}
void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
int32_t picture_buffer_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- // This ReusePictureBuffer() might have been in a pipe somewhere (queued in
- // IPC, or in a PostTask either at the sender or receiver) when we sent a
- // DismissPictureBuffer() for this |picture_buffer_id|. Account for such
- // potential "zombie" IDs here.
- if (dismissed_picture_ids_.erase(picture_buffer_id))
- return;
-
free_picture_ids_.push(picture_buffer_id);
TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
@@ -641,58 +922,139 @@ void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
}
strategy_->ReuseOnePictureBuffer(i->second);
-
- DoIOTask();
+ DoIOTask(true);
}
void AndroidVideoDecodeAccelerator::Flush() {
DCHECK(thread_checker_.CalledOnValidThread());
- Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
+ DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
}
-bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
+void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(surface_texture_.get());
- TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
- gfx::ScopedJavaSurface surface(surface_texture_.get());
+ // It's probably okay just to return here, since the codec will be configured
+ // asynchronously. It's unclear that any state for the new request could
+ // be different, unless somebody modifies |codec_config_| while we're already
+ // waiting for a codec. One shouldn't do that for thread safety.
+ DCHECK_NE(state_, WAITING_FOR_CODEC);
+
+ state_ = WAITING_FOR_CODEC;
+
+ // Tell the strategy that we're changing codecs. The codec itself could be
+ // used normally, since we don't replace it until we're back on the main
+ // thread. However, if we're using an output surface, then the incoming codec
+ // might access that surface while the main thread is drawing. Telling the
+ // strategy to forget the codec avoids this.
+ if (media_codec_) {
+ media_codec_.reset();
+ strategy_->CodecChanged(nullptr, output_picture_buffers_);
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ g_avda_timer.Pointer()->ConstructionTaskRunner();
+ CHECK(task_runner);
+
+ base::PostTaskAndReplyWithResult(
+ task_runner.get(), FROM_HERE,
+ base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread,
+ codec_config_),
+ base::Bind(&AndroidVideoDecodeAccelerator::OnCodecConfigured,
+ weak_this_factory_.GetWeakPtr()));
+}
+
+bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
+ state_ = WAITING_FOR_CODEC;
+ scoped_ptr<media::VideoCodecBridge> media_codec =
+ ConfigureMediaCodecOnAnyThread(codec_config_);
+ OnCodecConfigured(std::move(media_codec));
+ return !!media_codec_;
+}
+
+scoped_ptr<media::VideoCodecBridge>
+AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread(
+ scoped_refptr<CodecConfig> codec_config) {
+ TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
- jobject media_crypto = media_crypto_ ? media_crypto_->obj() : nullptr;
+ jobject media_crypto = codec_config->media_crypto_
+ ? codec_config->media_crypto_->obj()
+ : nullptr;
// |needs_protected_surface_| implies encrypted stream.
- DCHECK(!needs_protected_surface_ || media_crypto);
+ DCHECK(!codec_config->needs_protected_surface_ || media_crypto);
+
+ return scoped_ptr<media::VideoCodecBridge>(
+ media::VideoCodecBridge::CreateDecoder(
+ codec_config->codec_, codec_config->needs_protected_surface_,
+ codec_config->initial_expected_coded_size_,
+ codec_config->surface_.j_surface().obj(), media_crypto, true));
+}
+
+void AndroidVideoDecodeAccelerator::OnCodecConfigured(
+ scoped_ptr<media::VideoCodecBridge> media_codec) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(state_, WAITING_FOR_CODEC);
+
+ media_codec_ = std::move(media_codec);
+
+ // Record one instance of the codec being initialized.
+ RecordFormatChangedMetric(FormatChangedValue::CodecInitialized);
- // Pass a dummy 320x240 canvas size and let the codec signal the real size
- // when it's known from the bitstream.
- media_codec_.reset(media::VideoCodecBridge::CreateDecoder(
- codec_, needs_protected_surface_, gfx::Size(320, 240),
- surface.j_surface().obj(), media_crypto));
strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
+
+ // If we are supposed to notify that initialization is complete, then do so
+ // now. Otherwise, this is a reconfiguration.
+ if (deferred_initialization_pending_) {
+ NotifyInitializationComplete(!!media_codec_);
+ deferred_initialization_pending_ = false;
+ }
+
if (!media_codec_) {
- LOG(ERROR) << "Failed to create MediaCodec instance.";
- return false;
+ POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
+ return;
}
+ state_ = NO_ERROR;
+
ManageTimer(true);
- return true;
}
void AndroidVideoDecodeAccelerator::ResetCodecState() {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ // If there is already a reset in flight, then that counts. This can really
+ // only happen if somebody calls Reset.
+ if (state_ == WAITING_FOR_CODEC)
+ return;
+
bitstream_buffers_in_decoder_.clear();
- // We don't dismiss picture buffers here since we might not get a format
- // changed message to re-request them, such as during a seek. In that case,
- // we want to reuse the existing buffers. However, we're about to invalidate
- // all the output buffers, so we must be sure that the strategy no longer
- // refers to them.
+ if (pending_input_buf_index_ != -1) {
+ // The data for that index exists in the input buffer, but corresponding
+ // shm block been deleted. Check that it is safe to flush the coec, i.e.
+ // |pending_bitstream_buffers_| is empty.
+ // TODO(timav): keep shm block for that buffer and remove this restriction.
+ DCHECK(pending_bitstream_buffers_.empty());
+ pending_input_buf_index_ = -1;
+ }
+
+ if (state_ == WAITING_FOR_KEY)
+ state_ = NO_ERROR;
+
+ // We might increment error_sequence_token here to cancel any delayed errors,
+ // but right now it's unclear that it's safe to do so. If we are in an error
+ // state because of a codec error, then it would be okay. Otherwise, it's
+ // less obvious that we are exiting the error state. Since deferred errors
+ // are only intended for fullscreen transitions right now, we take the more
+ // conservative approach and let the errors post.
+ // TODO(liberato): revisit this once we sort out the error state a bit more.
// When codec is not in error state we can quickly reset (internally calls
// flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
- // (b/8125974, b/8347958) so we must stop() and reconfigure MediaCodec. The
- // full reconfigure is much slower and may cause visible freezing if done
- // mid-stream.
+ // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
+ // one. The full reconfigure is much slower and may cause visible freezing if
+ // done mid-stream.
if (state_ == NO_ERROR &&
base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
@@ -702,37 +1064,21 @@ void AndroidVideoDecodeAccelerator::ResetCodecState() {
strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
} else {
DVLOG(3) << __FUNCTION__
- << " Doing slow MediaCodec reset (stop/re-configure).";
- io_timer_.Stop();
- media_codec_->Stop();
+ << " Deleting the MediaCodec and creating a new one.";
+ g_avda_timer.Pointer()->StopTimer(this);
// Changing the codec will also notify the strategy to forget about any
// output buffers it has currently.
- ConfigureMediaCodec();
state_ = NO_ERROR;
+ ConfigureMediaCodecAsynchronously();
}
}
-void AndroidVideoDecodeAccelerator::DismissPictureBuffers() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DVLOG(3) << __FUNCTION__;
-
- for (const auto& pb : output_picture_buffers_) {
- strategy_->DismissOnePictureBuffer(pb.second);
- client_->DismissPictureBuffer(pb.first);
- dismissed_picture_ids_.insert(pb.first);
- }
- output_picture_buffers_.clear();
- std::queue<int32_t> empty;
- std::swap(free_picture_ids_, empty);
- picturebuffers_requested_ = false;
-}
-
void AndroidVideoDecodeAccelerator::Reset() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("media", "AVDA::Reset");
while (!pending_bitstream_buffers_.empty()) {
- int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().first.id();
+ int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
pending_bitstream_buffers_.pop();
if (bitstream_buffer_id != -1) {
@@ -745,8 +1091,13 @@ void AndroidVideoDecodeAccelerator::Reset() {
TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
bitstreams_notified_in_advance_.clear();
+ // Any error that is waiting to post can be ignored.
+ error_sequence_token_++;
+
ResetCodecState();
+ // Note that |media_codec_| might not yet be ready, but we can still post
+ // this anyway.
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
weak_this_factory_.GetWeakPtr()));
@@ -755,11 +1106,12 @@ void AndroidVideoDecodeAccelerator::Reset() {
void AndroidVideoDecodeAccelerator::Destroy() {
DCHECK(thread_checker_.CalledOnValidThread());
- bool have_context = make_context_current_.Run();
+ bool have_context = make_context_current_cb_.Run();
if (!have_context)
LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
- strategy_->Cleanup(have_context, output_picture_buffers_);
+ if (strategy_)
+ strategy_->Cleanup(have_context, output_picture_buffers_);
// If we have an OnFrameAvailable handler, tell it that we're going away.
if (on_frame_available_handler_) {
@@ -767,15 +1119,20 @@ void AndroidVideoDecodeAccelerator::Destroy() {
on_frame_available_handler_ = nullptr;
}
+ // Note that async codec construction might still be in progress. In that
+ // case, the codec will be deleted when it completes once we invalidate all
+ // our weak refs.
weak_this_factory_.InvalidateWeakPtrs();
if (media_codec_) {
- io_timer_.Stop();
- media_codec_->Stop();
+ g_avda_timer.Pointer()->StopTimer(this);
+ media_codec_.reset();
}
delete this;
}
-bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() {
+bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
return false;
}
@@ -790,7 +1147,29 @@ const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
base::WeakPtr<gpu::gles2::GLES2Decoder>
AndroidVideoDecodeAccelerator::GetGlDecoder() const {
- return gl_decoder_;
+ return get_gles2_decoder_cb_.Run();
+}
+
+gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
+ const media::PictureBuffer& picture_buffer) {
+ auto gles_decoder = GetGlDecoder();
+ RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
+ ILLEGAL_STATE, nullptr);
+ RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
+ "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
+ nullptr);
+ gpu::gles2::TextureManager* texture_manager =
+ gles_decoder->GetContextGroup()->texture_manager();
+ RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
+ ILLEGAL_STATE, nullptr);
+
+ DCHECK_LE(1u, picture_buffer.internal_texture_ids().size());
+ gpu::gles2::TextureRef* texture_ref =
+ texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]);
+ RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
+ nullptr);
+
+ return texture_ref;
}
void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
@@ -802,20 +1181,24 @@ void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
void AndroidVideoDecodeAccelerator::PostError(
const ::tracked_objects::Location& from_here,
media::VideoDecodeAccelerator::Error error) {
- base::MessageLoop::current()->PostTask(
- from_here, base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
- weak_this_factory_.GetWeakPtr(), error));
+ base::MessageLoop::current()->PostDelayedTask(
+ from_here,
+ base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
+ weak_this_factory_.GetWeakPtr(), error, error_sequence_token_),
+ (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta()));
state_ = ERROR;
}
void AndroidVideoDecodeAccelerator::OnMediaCryptoReady(
- media::MediaDrmBridge::JavaObjectPtr media_crypto,
+ media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
bool needs_protected_surface) {
DVLOG(1) << __FUNCTION__;
if (!media_crypto) {
LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream.";
- NotifyCdmAttached(false);
+ cdm_for_reference_holding_only_ = nullptr;
+ media_drm_bridge_cdm_context_ = nullptr;
+ NotifyInitializationComplete(false);
return;
}
@@ -825,23 +1208,24 @@ void AndroidVideoDecodeAccelerator::OnMediaCryptoReady(
// is not created yet.
DCHECK(!media_codec_);
- media_crypto_ = std::move(media_crypto);
- needs_protected_surface_ = needs_protected_surface;
+ codec_config_->media_crypto_ = std::move(media_crypto);
+ codec_config_->needs_protected_surface_ = needs_protected_surface;
// After receiving |media_crypto_| we can configure MediaCodec.
- const bool success = ConfigureMediaCodec();
- NotifyCdmAttached(success);
+ ConfigureMediaCodecAsynchronously();
}
void AndroidVideoDecodeAccelerator::OnKeyAdded() {
DVLOG(1) << __FUNCTION__;
- // TODO(timav): Figure out whether stopping the pipeline in response to
- // NO_KEY error and restarting it here has significant benefits (e.g. saving
- // power). Right now do nothing here.
+
+ if (state_ == WAITING_FOR_KEY)
+ state_ = NO_ERROR;
+
+ DoIOTask(true);
}
-void AndroidVideoDecodeAccelerator::NotifyCdmAttached(bool success) {
- client_->NotifyCdmAttached(success);
+void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
+ client_->NotifyInitializationComplete(success);
}
void AndroidVideoDecodeAccelerator::NotifyPictureReady(
@@ -863,7 +1247,13 @@ void AndroidVideoDecodeAccelerator::NotifyResetDone() {
}
void AndroidVideoDecodeAccelerator::NotifyError(
- media::VideoDecodeAccelerator::Error error) {
+ media::VideoDecodeAccelerator::Error error,
+ int token) {
+ DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
+ << " current: " << error_sequence_token_;
+ if (token != error_sequence_token_)
+ return;
+
client_->NotifyError(error);
}
@@ -871,45 +1261,72 @@ void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
bool should_be_running = true;
base::TimeTicks now = base::TimeTicks::Now();
- if (!did_work) {
+ if (!did_work && !most_recent_work_.is_null()) {
// Make sure that we have done work recently enough, else stop the timer.
- if (now - most_recent_work_ > IdleTimerTimeOut())
+ if (now - most_recent_work_ > IdleTimerTimeOut()) {
+ most_recent_work_ = base::TimeTicks();
should_be_running = false;
+ }
} else {
most_recent_work_ = now;
}
- if (should_be_running && !io_timer_.IsRunning()) {
- io_timer_.Start(FROM_HERE, DecodePollDelay(), this,
- &AndroidVideoDecodeAccelerator::DoIOTask);
- } else if (!should_be_running && io_timer_.IsRunning()) {
- io_timer_.Stop();
- }
+ if (should_be_running)
+ g_avda_timer.Pointer()->StartTimer(this);
+ else
+ g_avda_timer.Pointer()->StopTimer(this);
}
// static
-bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableUnifiedMediaPipeline);
+bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy(
+ const gpu::GpuPreferences& gpu_preferences) {
+ // TODO(liberato, watk): Figure out what we want to do about zero copy for
+ // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
+ return !gpu_preferences.enable_threaded_texture_mailboxes;
}
// static
media::VideoDecodeAccelerator::Capabilities
-AndroidVideoDecodeAccelerator::GetCapabilities() {
+AndroidVideoDecodeAccelerator::GetCapabilities(
+ const gpu::GpuPreferences& gpu_preferences) {
Capabilities capabilities;
SupportedProfiles& profiles = capabilities.supported_profiles;
- SupportedProfile profile;
-
- profile.profile = media::VP8PROFILE_ANY;
- profile.min_resolution.SetSize(0, 0);
- profile.max_resolution.SetSize(1920, 1088);
- profiles.push_back(profile);
+ if (media::MediaCodecUtil::IsVp8DecoderAvailable()) {
+ SupportedProfile profile;
+ profile.profile = media::VP8PROFILE_ANY;
+ profile.min_resolution.SetSize(0, 0);
+ profile.max_resolution.SetSize(1920, 1088);
+ // If we know MediaCodec will just create a software codec, prefer our
+ // internal software decoder instead. It's more up to date and secured
+ // within the renderer sandbox. However if the content is encrypted, we
+ // must use MediaCodec anyways since MediaDrm offers no way to decrypt
+ // the buffers and let us use our internal software decoders.
+ profile.encrypted_only = media::VideoCodecBridge::IsKnownUnaccelerated(
+ media::kCodecVP8, media::MEDIA_CODEC_DECODER);
+ profiles.push_back(profile);
+ }
- profile.profile = media::VP9PROFILE_ANY;
- profile.min_resolution.SetSize(0, 0);
- profile.max_resolution.SetSize(1920, 1088);
- profiles.push_back(profile);
+ if (media::MediaCodecUtil::IsVp9DecoderAvailable()) {
+ SupportedProfile profile;
+ profile.min_resolution.SetSize(0, 0);
+ profile.max_resolution.SetSize(1920, 1088);
+ // If we know MediaCodec will just create a software codec, prefer our
+ // internal software decoder instead. It's more up to date and secured
+ // within the renderer sandbox. However if the content is encrypted, we
+ // must use MediaCodec anyways since MediaDrm offers no way to decrypt
+ // the buffers and let us use our internal software decoders.
+ profile.encrypted_only = media::VideoCodecBridge::IsKnownUnaccelerated(
+ media::kCodecVP9, media::MEDIA_CODEC_DECODER);
+ profile.profile = media::VP9PROFILE_PROFILE0;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE1;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE2;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE3;
+ profiles.push_back(profile);
+ }
for (const auto& supported_profile : kSupportedH264Profiles) {
SupportedProfile profile;
@@ -922,9 +1339,15 @@ AndroidVideoDecodeAccelerator::GetCapabilities() {
profiles.push_back(profile);
}
- if (UseDeferredRenderingStrategy()) {
- capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
+ capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
+ SUPPORTS_DEFERRED_INITIALIZATION;
+ if (UseDeferredRenderingStrategy(gpu_preferences)) {
+ capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE;
+ if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
+ capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
+ SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
+ }
}
return capabilities;
diff --git a/chromium/content/common/gpu/media/android_video_decode_accelerator.h b/chromium/content/common/gpu/media/android_video_decode_accelerator.h
index 1dd6816a72d..1e0543d3fc5 100644
--- a/chromium/content/common/gpu/media/android_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/android_video_decode_accelerator.h
@@ -18,11 +18,14 @@
#include "base/timer/timer.h"
#include "content/common/content_export.h"
#include "content/common/gpu/media/avda_state_provider.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "media/base/android/media_drm_bridge.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "media/base/android/media_drm_bridge_cdm_context.h"
#include "media/base/android/sdk_media_codec_bridge.h"
#include "media/base/media_keys.h"
#include "media/video/video_decode_accelerator.h"
+#include "ui/gl/android/scoped_java_surface.h"
namespace gfx {
class SurfaceTexture;
@@ -39,7 +42,7 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
: public media::VideoDecodeAccelerator,
public AVDAStateProvider {
public:
- typedef std::map<int32_t, media::PictureBuffer> OutputBufferMap;
+ using OutputBufferMap = std::map<int32_t, media::PictureBuffer>;
// A BackingStrategy is responsible for making a PictureBuffer's texture
// contain the image that a MediaCodec decoder buffer tells it to.
@@ -47,20 +50,26 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
public:
virtual ~BackingStrategy() {}
- // Called after the state provider is given, but before any other
- // calls to the BackingStrategy.
- virtual void Initialize(AVDAStateProvider* provider) = 0;
+ // Must be called before anything else. If surface_view_id is not equal to
+ // |kNoSurfaceID| it refers to a SurfaceView that the strategy must render
+ // to.
+ // Returns the Java surface to configure MediaCodec with.
+ virtual gfx::ScopedJavaSurface Initialize(int surface_view_id) = 0;
// Called before the AVDA does any Destroy() work. This will be
// the last call that the BackingStrategy receives.
virtual void Cleanup(bool have_context,
const OutputBufferMap& buffer_map) = 0;
+ // This returns the SurfaceTexture created by Initialize, or nullptr if
+ // the strategy was initialized with a SurfaceView.
+ virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture() const = 0;
+
// Return the GL texture target that the PictureBuffer textures use.
virtual uint32_t GetTextureTarget() const = 0;
- // Create and return a surface texture for the MediaCodec to use.
- virtual scoped_refptr<gfx::SurfaceTexture> CreateSurfaceTexture() = 0;
+ // Return the size to use when requesting picture buffers.
+ virtual gfx::Size GetPictureBufferSize() const = 0;
// Make the provided PictureBuffer draw the image that is represented by
// the decoded output buffer at codec_buffer_index.
@@ -70,16 +79,13 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// Notify strategy that a picture buffer has been assigned.
virtual void AssignOnePictureBuffer(
- const media::PictureBuffer& picture_buffer) {}
+ const media::PictureBuffer& picture_buffer,
+ bool have_context) {}
// Notify strategy that a picture buffer has been reused.
virtual void ReuseOnePictureBuffer(
const media::PictureBuffer& picture_buffer) {}
- // Notify strategy that we are about to dismiss a picture buffer.
- virtual void DismissOnePictureBuffer(
- const media::PictureBuffer& picture_buffer) {}
-
// Notify strategy that we have a new android MediaCodec instance. This
// happens when we're starting up or re-configuring mid-stream. Any
// previously provided codec should no longer be referenced.
@@ -91,11 +97,22 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// Notify the strategy that a frame is available. This callback can happen
// on any thread at any time.
virtual void OnFrameAvailable() = 0;
+
+ // Whether the pictures produced by this backing strategy are overlayable.
+ virtual bool ArePicturesOverlayable() = 0;
+
+ // Size may have changed due to resolution change since the last time this
+ // PictureBuffer was used. Update the size of the picture buffer to
+ // |new_size| and also update any size-dependent state (e.g. size of
+ // associated texture). Callers should set the correct GL context prior to
+ // calling.
+ virtual void UpdatePictureBufferSize(media::PictureBuffer* picture_buffer,
+ const gfx::Size& new_size) = 0;
};
AndroidVideoDecodeAccelerator(
- const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder,
- const base::Callback<bool(void)>& make_context_current);
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb);
~AndroidVideoDecodeAccelerator() override;
@@ -109,31 +126,98 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
// AVDAStateProvider implementation:
const gfx::Size& GetSize() const override;
const base::ThreadChecker& ThreadChecker() const override;
base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const override;
+ gpu::gles2::TextureRef* GetTextureForPicture(
+ const media::PictureBuffer& picture_buffer) override;
void PostError(const ::tracked_objects::Location& from_here,
media::VideoDecodeAccelerator::Error error) override;
- static media::VideoDecodeAccelerator::Capabilities GetCapabilities();
+ static media::VideoDecodeAccelerator::Capabilities GetCapabilities(
+ const gpu::GpuPreferences& gpu_preferences);
// Notifies about SurfaceTexture::OnFrameAvailable. This can happen on any
// thread at any time!
void OnFrameAvailable();
private:
+ friend class AVDATimerManager;
+
+ // TODO(timav): evaluate the need for more states in the AVDA state machine.
enum State {
NO_ERROR,
ERROR,
+ // Set when we are asynchronously constructing the codec. Will transition
+ // to NO_ERROR or ERROR depending on success.
+ WAITING_FOR_CODEC,
+ // Set when we have a codec, but it doesn't yet have a key.
+ WAITING_FOR_KEY,
+ WAITING_FOR_EOS,
};
- static const base::TimeDelta kDecodePollDelay;
+ // Configuration info for MediaCodec.
+ // This is used to shuttle configuration info between threads without needing
+ // to worry about the lifetime of the AVDA instance. All of these should not
+ // be modified while |state_| is WAITING_FOR_CODEC.
+ class CodecConfig : public base::RefCountedThreadSafe<CodecConfig> {
+ public:
+ CodecConfig();
+
+ // Codec type. Used when we configure media codec.
+ media::VideoCodec codec_ = media::kUnknownVideoCodec;
+
+ // Whether encryption scheme requires to use protected surface.
+ bool needs_protected_surface_ = false;
+
+ // The surface that MediaCodec is configured to output to. It's created by
+ // the backing strategy.
+ gfx::ScopedJavaSurface surface_;
+
+ // The MediaCrypto object is used in the MediaCodec.configure() in case of
+ // an encrypted stream.
+ media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto_;
+
+ // Initial coded size. The actual size might change at any time, so this
+ // is only a hint.
+ gfx::Size initial_expected_coded_size_;
+
+ protected:
+ friend class base::RefCountedThreadSafe<CodecConfig>;
+ virtual ~CodecConfig();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CodecConfig);
+ };
// Configures |media_codec_| with the given codec parameters from the client.
- bool ConfigureMediaCodec();
+ // This configuration will (probably) not be complete before this call
+ // returns. Multiple calls before completion will be ignored. |state_|
+ // must be NO_ERROR or WAITING_FOR_CODEC. Note that, once you call this,
+ // you should be careful to avoid modifying members of |codec_config_| until
+ // |state_| is no longer WAITING_FOR_CODEC.
+ void ConfigureMediaCodecAsynchronously();
+
+ // Like ConfigureMediaCodecAsynchronously, but synchronous. Returns true if
+ // and only if |media_codec_| is non-null. Since all configuration is done
+ // synchronously, there is no concern with modifying |codec_config_| after
+ // this returns.
+ bool ConfigureMediaCodecSynchronously();
+
+ // Instantiate a media codec using |codec_config|.
+ // This may be called on any thread.
+ static scoped_ptr<media::VideoCodecBridge> ConfigureMediaCodecOnAnyThread(
+ scoped_refptr<CodecConfig> codec_config);
+
+ // Called on the main thread to update |media_codec_| and complete codec
+ // configuration. |media_codec| will be null if configuration failed.
+ void OnCodecConfigured(scoped_ptr<media::VideoCodecBridge> media_codec);
// Sends the decoded frame specified by |codec_buffer_index| to the client.
void SendDecodedFrameToClient(int32_t codec_buffer_index,
@@ -142,7 +226,7 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// Does pending IO tasks if any. Once this is called, it polls |media_codec_|
// until it finishes pending tasks. For the polling, |kDecodePollDelay| is
// used.
- void DoIOTask();
+ void DoIOTask(bool start_timer);
// Feeds input data to |media_codec_|. This checks
// |pending_bitstream_buffers_| and queues a buffer to |media_codec_|.
@@ -157,15 +241,20 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// Requests picture buffers from the client.
void RequestPictureBuffers();
+ // Decode the content in the |bitstream_buffer|. Note that a
+ // |bitstream_buffer| of id as -1 indicates a flush command.
+ void DecodeBuffer(const media::BitstreamBuffer& bitstream_buffer);
+
// This callback is called after CDM obtained a MediaCrypto object.
- void OnMediaCryptoReady(media::MediaDrmBridge::JavaObjectPtr media_crypto,
- bool needs_protected_surface);
+ void OnMediaCryptoReady(
+ media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto,
+ bool needs_protected_surface);
// This callback is called when a new key is added to CDM.
void OnKeyAdded();
- // Notifies the client of the CDM setting result.
- void NotifyCdmAttached(bool success);
+ // Notifies the client of the result of deferred initialization.
+ void NotifyInitializationComplete(bool success);
// Notifies the client about the availability of a picture.
void NotifyPictureReady(const media::Picture& picture);
@@ -181,7 +270,12 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
void NotifyResetDone();
// Notifies about decoding errors.
- void NotifyError(media::VideoDecodeAccelerator::Error error);
+ // Note: you probably don't want to call this directly. Use PostError or
+ // RETURN_ON_FAILURE, since we can defer error reporting to keep the pipeline
+ // from breaking. NotifyError will do so immediately, PostError may wait.
+ // |token| has to match |error_sequence_token_|, or else it's assumed to be
+ // from a post that's prior to a previous reset, and ignored.
+ void NotifyError(media::VideoDecodeAccelerator::Error error, int token);
// Start or stop our work-polling timer based on whether we did any work, and
// how long it has been since we've done work. Calling this with true will
@@ -194,12 +288,9 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// is still valid and should be processed.
void ResetCodecState();
- // Dismiss all |output_picture_buffers_| in preparation for requesting new
- // ones.
- void DismissPictureBuffers();
-
// Return true if and only if we should use deferred rendering.
- static bool UseDeferredRenderingStrategy();
+ static bool UseDeferredRenderingStrategy(
+ const gpu::GpuPreferences& gpu_preferences);
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
@@ -208,17 +299,14 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
Client* client_;
// Callback to set the correct gl context.
- base::Callback<bool(void)> make_context_current_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
- // Codec type. Used when we configure media codec.
- media::VideoCodec codec_;
+ // Callback to get the GLES2Decoder instance.
+ GetGLES2DecoderCallback get_gles2_decoder_cb_;
// Whether the stream is encrypted.
bool is_encrypted_;
- // Whether encryption scheme requires to use protected surface.
- bool needs_protected_surface_;
-
// The current state of this class. For now, this is used only for setting
// error state.
State state_;
@@ -231,17 +319,9 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// decoded frames to the client.
std::queue<int32_t> free_picture_ids_;
- // Picture buffer ids which have been dismissed and not yet re-assigned. Used
- // to ignore ReusePictureBuffer calls that were in flight when the
- // DismissPictureBuffer call was made.
- std::set<int32_t> dismissed_picture_ids_;
-
// The low-level decoder which Android SDK provides.
scoped_ptr<media::VideoCodecBridge> media_codec_;
- // A container of texture. Used to set a texture to |media_codec_|.
- scoped_refptr<gfx::SurfaceTexture> surface_texture_;
-
// Set to true after requesting picture buffers to the client.
bool picturebuffers_requested_;
@@ -249,11 +329,8 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
gfx::Size size_;
// Encoded bitstream buffers to be passed to media codec, queued until an
- // input buffer is available, along with the time when they were first
- // enqueued.
- typedef std::queue<std::pair<media::BitstreamBuffer, base::Time> >
- PendingBitstreamBuffers;
- PendingBitstreamBuffers pending_bitstream_buffers_;
+ // input buffer is available.
+ std::queue<media::BitstreamBuffer> pending_bitstream_buffers_;
// A map of presentation timestamp to bitstream buffer id for the bitstream
// buffers that have been submitted to the decoder but haven't yet produced an
@@ -265,12 +342,6 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
std::list<int32_t> bitstreams_notified_in_advance_;
- // Owner of the GL context. Used to restore the context state.
- base::WeakPtr<gpu::gles2::GLES2Decoder> gl_decoder_;
-
- // Repeating timer responsible for draining pending IO to the codec.
- base::RepeatingTimer io_timer_;
-
// Backing strategy that we'll use to connect PictureBuffers to frames.
scoped_ptr<BackingStrategy> strategy_;
@@ -283,16 +354,33 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator
// CDM related stuff.
- // Holds a ref-count to the CDM.
- scoped_refptr<media::MediaKeys> cdm_;
+ // Holds a ref-count to the CDM to avoid using the CDM after it's destroyed.
+ scoped_refptr<media::MediaKeys> cdm_for_reference_holding_only_;
+
+ media::MediaDrmBridgeCdmContext* media_drm_bridge_cdm_context_;
// MediaDrmBridge requires registration/unregistration of the player, this
// registration id is used for this.
int cdm_registration_id_;
- // The MediaCrypto object is used in the MediaCodec.configure() in case of
- // an encrypted stream.
- media::MediaDrmBridge::JavaObjectPtr media_crypto_;
+ // Configuration that we use for MediaCodec.
+ // Do not update any of its members while |state_| is WAITING_FOR_CODEC.
+ scoped_refptr<CodecConfig> codec_config_;
+
+ // Index of the dequeued and filled buffer that we keep trying to enqueue.
+ // Such buffer appears in MEDIA_CODEC_NO_KEY processing.
+ int pending_input_buf_index_;
+
+ // Monotonically increasing value that is used to prevent old, delayed errors
+ // from being sent after a reset.
+ int error_sequence_token_;
+
+ // PostError will defer sending an error if and only if this is true.
+ bool defer_errors_;
+
+ // True if and only if VDA initialization is deferred, and we have not yet
+ // called NotifyInitializationComplete.
+ bool deferred_initialization_pending_;
// WeakPtrFactory for posting tasks back to |this|.
base::WeakPtrFactory<AndroidVideoDecodeAccelerator> weak_this_factory_;
diff --git a/chromium/content/common/gpu/media/android_video_decode_accelerator_unittest.cc b/chromium/content/common/gpu/media/android_video_decode_accelerator_unittest.cc
index 3cd79157162..d21ad9e58a8 100644
--- a/chromium/content/common/gpu/media/android_video_decode_accelerator_unittest.cc
+++ b/chromium/content/common/gpu/media/android_video_decode_accelerator_unittest.cc
@@ -27,13 +27,15 @@ bool MockMakeContextCurrent() {
return true;
}
+static base::WeakPtr<gpu::gles2::GLES2Decoder> MockGetGLES2Decoder(
+ const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) {
+ return decoder;
+}
+
} // namespace
namespace content {
-// TODO(felipeg): Add more unit tests to test the ordinary behavior of
-// AndroidVideoDecodeAccelerator.
-// http://crbug.com/178647
class MockVideoDecodeAcceleratorClient
: public media::VideoDecodeAccelerator::Client {
public:
@@ -42,6 +44,7 @@ class MockVideoDecodeAcceleratorClient
// VideoDecodeAccelerator::Client implementation.
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
+ uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override {}
void DismissPictureBuffer(int32_t picture_buffer_id) override {}
@@ -60,8 +63,6 @@ class AndroidVideoDecodeAcceleratorTest : public testing::Test {
void SetUp() override {
JNIEnv* env = base::android::AttachCurrentThread();
media::RegisterJni(env);
- // TODO(felipeg): fix GL bindings, so that the decoder can perform GL
- // calls.
// Start message loop because
// AndroidVideoDecodeAccelerator::ConfigureMediaCodec() starts a timer task.
@@ -72,15 +73,19 @@ class AndroidVideoDecodeAcceleratorTest : public testing::Test {
scoped_ptr<MockVideoDecodeAcceleratorClient> client(
new MockVideoDecodeAcceleratorClient());
accelerator_.reset(new AndroidVideoDecodeAccelerator(
- decoder->AsWeakPtr(), base::Bind(&MockMakeContextCurrent)));
+ base::Bind(&MockMakeContextCurrent),
+ base::Bind(&MockGetGLES2Decoder, decoder->AsWeakPtr())));
}
bool Configure(media::VideoCodec codec) {
AndroidVideoDecodeAccelerator* accelerator =
static_cast<AndroidVideoDecodeAccelerator*>(accelerator_.get());
- accelerator->surface_texture_ = gfx::SurfaceTexture::Create(0);
- accelerator->codec_ = codec;
- return accelerator->ConfigureMediaCodec();
+ scoped_refptr<gfx::SurfaceTexture> surface_texture =
+ gfx::SurfaceTexture::Create(0);
+ accelerator->codec_config_->surface_ =
+ gfx::ScopedJavaSurface(surface_texture.get());
+ accelerator->codec_config_->codec_ = codec;
+ return accelerator->ConfigureMediaCodecSynchronously();
}
private:
diff --git a/chromium/content/common/gpu/media/android_video_encode_accelerator.cc b/chromium/content/common/gpu/media/android_video_encode_accelerator.cc
index eb383081d7f..ac2ff39e9b7 100644
--- a/chromium/content/common/gpu/media/android_video_encode_accelerator.cc
+++ b/chromium/content/common/gpu/media/android_video_encode_accelerator.cc
@@ -7,13 +7,12 @@
#include <set>
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/public/common/content_switches.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/ipc/service/gpu_channel.h"
#include "media/base/android/media_codec_util.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/limits.h"
@@ -95,8 +94,6 @@ static bool GetSupportedColorFormatForMime(const std::string& mime,
AndroidVideoEncodeAccelerator::AndroidVideoEncodeAccelerator()
: num_buffers_at_codec_(0),
- num_output_buffers_(-1),
- output_buffers_capacity_(0),
last_set_bitrate_(0) {}
AndroidVideoEncodeAccelerator::~AndroidVideoEncodeAccelerator() {
@@ -107,12 +104,6 @@ media::VideoEncodeAccelerator::SupportedProfiles
AndroidVideoEncodeAccelerator::GetSupportedProfiles() {
SupportedProfiles profiles;
-#if defined(ENABLE_WEBRTC)
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- if (cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding))
- return profiles;
-#endif
-
const struct {
const media::VideoCodec codec;
const media::VideoCodecProfile profile;
@@ -123,6 +114,11 @@ AndroidVideoEncodeAccelerator::GetSupportedProfiles() {
};
for (const auto& supported_codec : kSupportedCodecs) {
+ if (supported_codec.codec == media::kCodecVP8 &&
+ !media::MediaCodecUtil::IsVp8EncoderAvailable()) {
+ continue;
+ }
+
if (VideoCodecBridge::IsKnownUnaccelerated(supported_codec.codec,
media::MEDIA_CODEC_ENCODER)) {
continue;
@@ -164,17 +160,24 @@ bool AndroidVideoEncodeAccelerator::Initialize(
std::string mime_type;
media::VideoCodec codec;
+ // The client should be prepared to feed at least this many frames into the
+ // encoder before being returned any output frames, since the encoder may
+ // need to hold onto some subset of inputs as reference pictures.
+ uint32_t frame_input_count;
if (output_profile == media::VP8PROFILE_ANY) {
codec = media::kCodecVP8;
mime_type = "video/x-vnd.on2.vp8";
+ frame_input_count = 1;
} else if (output_profile == media::H264PROFILE_BASELINE ||
output_profile == media::H264PROFILE_MAIN) {
codec = media::kCodecH264;
mime_type = "video/avc";
+ frame_input_count = 30;
} else {
return false;
}
+ frame_size_ = input_visible_size;
last_set_bitrate_ = initial_bitrate;
// Only consider using MediaCodec if it's likely backed by hardware.
@@ -202,15 +205,16 @@ bool AndroidVideoEncodeAccelerator::Initialize(
return false;
}
- num_output_buffers_ = media_codec_->GetOutputBuffersCount();
- output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity();
+ // Conservative upper bound for output buffer size: decoded size + 2KB.
+ const size_t output_buffer_capacity =
+ VideoFrame::AllocationSize(format, input_visible_size) + 2048;
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers,
client_ptr_factory_->GetWeakPtr(),
- num_output_buffers_,
+ frame_input_count,
input_visible_size,
- output_buffers_capacity_));
+ output_buffer_capacity));
return true;
}
@@ -238,7 +242,8 @@ void AndroidVideoEncodeAccelerator::Encode(
DCHECK(thread_checker_.CalledOnValidThread());
RETURN_ON_FAILURE(frame->format() == media::PIXEL_FORMAT_I420,
"Unexpected format", kInvalidArgumentError);
-
+ RETURN_ON_FAILURE(frame->visible_rect().size() == frame_size_,
+ "Unexpected resolution", kInvalidArgumentError);
// MediaCodec doesn't have a way to specify stride for non-Packed formats, so
// we insist on being called with packed frames and no cropping :(
RETURN_ON_FAILURE(frame->row_bytes(VideoFrame::kYPlane) ==
@@ -260,9 +265,6 @@ void AndroidVideoEncodeAccelerator::UseOutputBitstreamBuffer(
const media::BitstreamBuffer& buffer) {
DVLOG(3) << __PRETTY_FUNCTION__ << ": bitstream_buffer_id=" << buffer.id();
DCHECK(thread_checker_.CalledOnValidThread());
- RETURN_ON_FAILURE(buffer.size() >= media_codec_->GetOutputBuffersCapacity(),
- "Output buffers too small!",
- kInvalidArgumentError);
available_bitstream_buffers_.push_back(buffer);
DoIOTask();
}
@@ -331,7 +333,9 @@ void AndroidVideoEncodeAccelerator::QueueInput() {
uint8_t* buffer = NULL;
size_t capacity = 0;
- media_codec_->GetInputBuffer(input_buf_index, &buffer, &capacity);
+ status = media_codec_->GetInputBuffer(input_buf_index, &buffer, &capacity);
+ RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK, "GetInputBuffer failed.",
+ kPlatformFailureError);
size_t queued_size =
VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, frame->coded_size());
@@ -373,21 +377,6 @@ void AndroidVideoEncodeAccelerator::QueueInput() {
pending_frames_.pop();
}
-bool AndroidVideoEncodeAccelerator::DoOutputBuffersSuffice() {
- // If this returns false ever, then the VEA::Client interface will need to
- // grow a DismissBitstreamBuffer() call, and VEA::Client impls will have to be
- // prepared to field multiple requests to RequireBitstreamBuffers().
- int count = media_codec_->GetOutputBuffersCount();
- size_t capacity = media_codec_->GetOutputBuffersCapacity();
- bool ret = count <= num_output_buffers_ &&
- capacity <= output_buffers_capacity_;
- LOG_IF(ERROR, !ret) << "Need more/bigger buffers; before: "
- << num_output_buffers_ << "x" << output_buffers_capacity_
- << ", now: " << count << "x" << capacity;
- UMA_HISTOGRAM_BOOLEAN("Media.AVEA.OutputBuffersSuffice", ret);
- return ret;
-}
-
void AndroidVideoEncodeAccelerator::DequeueOutput() {
if (!client_ptr_factory_->GetWeakPtr() ||
available_bitstream_buffers_.empty() || num_buffers_at_codec_ == 0) {
@@ -410,13 +399,14 @@ void AndroidVideoEncodeAccelerator::DequeueOutput() {
// Unreachable because of previous statement, but included for clarity.
return;
- case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: // Fall-through.
- case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
- RETURN_ON_FAILURE(DoOutputBuffersSuffice(),
- "Bitstream now requires more/larger buffers",
+ case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED:
+ RETURN_ON_FAILURE(false, "Unexpected output format change",
kPlatformFailureError);
break;
+ case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
+ break;
+
case media::MEDIA_CODEC_OK:
DCHECK_GE(buf_index, 0);
break;
@@ -429,17 +419,17 @@ void AndroidVideoEncodeAccelerator::DequeueOutput() {
media::BitstreamBuffer bitstream_buffer = available_bitstream_buffers_.back();
available_bitstream_buffers_.pop_back();
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(bitstream_buffer.handle(), false));
- RETURN_ON_FAILURE(shm->Map(bitstream_buffer.size()),
- "Failed to map SHM",
- kPlatformFailureError);
- RETURN_ON_FAILURE(size <= shm->mapped_size(),
- "Encoded buffer too large: " << size << ">"
- << shm->mapped_size(),
+ scoped_ptr<SharedMemoryRegion> shm(
+ new SharedMemoryRegion(bitstream_buffer, false));
+ RETURN_ON_FAILURE(shm->Map(), "Failed to map SHM", kPlatformFailureError);
+ RETURN_ON_FAILURE(size <= shm->size(),
+ "Encoded buffer too large: " << size << ">" << shm->size(),
kPlatformFailureError);
- media_codec_->CopyFromOutputBuffer(buf_index, offset, shm->memory(), size);
+ media::MediaCodecStatus status = media_codec_->CopyFromOutputBuffer(
+ buf_index, offset, shm->memory(), size);
+ RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK,
+ "CopyFromOutputBuffer failed", kPlatformFailureError);
media_codec_->ReleaseOutputBuffer(buf_index, false);
--num_buffers_at_codec_;
diff --git a/chromium/content/common/gpu/media/android_video_encode_accelerator.h b/chromium/content/common/gpu/media/android_video_encode_accelerator.h
index 426360dca7c..0de3d1866b1 100644
--- a/chromium/content/common/gpu/media/android_video_encode_accelerator.h
+++ b/chromium/content/common/gpu/media/android_video_encode_accelerator.h
@@ -67,9 +67,6 @@ class CONTENT_EXPORT AndroidVideoEncodeAccelerator
void QueueInput();
void DequeueOutput();
- // Returns true if we don't need more or bigger output buffers.
- bool DoOutputBuffersSuffice();
-
// Start & stop |io_timer_| if the time seems right.
void MaybeStartIOTimer();
void MaybeStopIOTimer();
@@ -103,9 +100,9 @@ class CONTENT_EXPORT AndroidVideoEncodeAccelerator
// appearing to move forward.
base::TimeDelta fake_input_timestamp_;
- // Number of requested output buffers and their capacity.
- int num_output_buffers_; // -1 until RequireBitstreamBuffers.
- size_t output_buffers_capacity_; // 0 until RequireBitstreamBuffers.
+ // Resolution of input stream. Set once in initialization and not allowed to
+ // change after.
+ gfx::Size frame_size_;
uint32_t last_set_bitrate_; // In bps.
diff --git a/chromium/content/common/gpu/media/avda_codec_image.cc b/chromium/content/common/gpu/media/avda_codec_image.cc
index 1df753d167e..5830433cdf2 100644
--- a/chromium/content/common/gpu/media/avda_codec_image.cc
+++ b/chromium/content/common/gpu/media/avda_codec_image.cc
@@ -24,16 +24,17 @@ AVDACodecImage::AVDACodecImage(
const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder,
const scoped_refptr<gfx::SurfaceTexture>& surface_texture)
: shared_state_(shared_state),
- codec_buffer_index_(-1),
+ codec_buffer_index_(kInvalidCodecBufferIndex),
media_codec_(codec),
decoder_(decoder),
surface_texture_(surface_texture),
detach_surface_texture_on_destruction_(false),
- texture_(0),
- need_shader_info_(true),
- texmatrix_uniform_location_(-1) {
+ texture_(0) {
+ // Default to a sane guess of "flip Y", just in case we can't get
+ // the matrix on the first call.
memset(gl_matrix_, 0, sizeof(gl_matrix_));
- gl_matrix_[0] = gl_matrix_[5] = gl_matrix_[10] = gl_matrix_[15] = 1.0f;
+ gl_matrix_[0] = gl_matrix_[10] = gl_matrix_[15] = 1.0f;
+ gl_matrix_[5] = -1.0f;
}
AVDACodecImage::~AVDACodecImage() {}
@@ -55,38 +56,35 @@ bool AVDACodecImage::BindTexImage(unsigned target) {
void AVDACodecImage::ReleaseTexImage(unsigned target) {}
bool AVDACodecImage::CopyTexImage(unsigned target) {
+ if (!surface_texture_)
+ return false;
+
if (target != GL_TEXTURE_EXTERNAL_OES)
return false;
- // Verify that the currently bound texture is the right one. If we're not
- // copying to a Texture that shares our service_id, then we can't do much.
- // This will force a copy.
- // TODO(liberato): Fall back to a copy that uses the texture matrix.
GLint bound_service_id = 0;
glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+ // We insist that the currently bound texture is the right one. We could
+ // make a new glimage from a 2D image.
if (bound_service_id != shared_state_->surface_texture_service_id())
return false;
- // Attach the surface texture to our GL context if needed.
+ // If the surface texture isn't attached yet, then attach it. Note that this
+ // will be to the texture in |shared_state_|, because of the checks above.
if (!shared_state_->surface_texture_is_attached())
AttachSurfaceTextureToContext();
- // Make sure that we have the right image in the front buffer.
- UpdateSurfaceTexture();
-
- InstallTextureMatrix();
-
- // TODO(liberato): Handle the texture matrix properly.
- // Either we can update the shader with it or we can move all of the logic
- // to updateTexImage() to the right place in the cc to send it to the shader.
- // For now, we just skip it. crbug.com/530681
+ // Make sure that we have the right image in the front buffer. Note that the
+ // bound_service_id is guaranteed to be equal to the surface texture's client
+ // texture id, so we can skip preserving it if the right context is current.
+ UpdateSurfaceTexture(kDontRestoreBindings);
// By setting image state to UNBOUND instead of COPIED we ensure that
// CopyTexImage() is called each time the surface texture is used for drawing.
// It would be nice if we could do this via asking for the currently bound
// Texture, but the active unit never seems to change.
- texture_->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gpu::gles2::Texture::UNBOUND);
+ texture_->SetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
+ gpu::gles2::Texture::UNBOUND);
return true;
}
@@ -102,16 +100,29 @@ bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
gfx::OverlayTransform transform,
const gfx::Rect& bounds_rect,
const gfx::RectF& crop_rect) {
- return false;
+ // This should only be called when we're rendering to a SurfaceView.
+ if (surface_texture_) {
+ DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is "
+ "SurfaceTexture backed.";
+ return false;
+ }
+
+ if (codec_buffer_index_ != kInvalidCodecBufferIndex) {
+ media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
+ codec_buffer_index_ = kInvalidCodecBufferIndex;
+ }
+ return true;
}
void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
const std::string& dump_name) {}
-void AVDACodecImage::UpdateSurfaceTexture() {
+void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
+ DCHECK(surface_texture_);
+
// Render via the media codec if needed.
- if (codec_buffer_index_ <= -1 || !media_codec_)
+ if (!IsCodecBufferOutstanding())
return;
// The decoder buffer is still pending.
@@ -123,15 +134,24 @@ void AVDACodecImage::UpdateSurfaceTexture() {
}
// Don't bother to check if we're rendered again.
- codec_buffer_index_ = -1;
+ codec_buffer_index_ = kInvalidCodecBufferIndex;
// Swap the rendered image to the front.
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
- if (!shared_state_->context()->IsCurrent(NULL)) {
- scoped_make_current.reset(new ui::ScopedMakeCurrent(
- shared_state_->context(), shared_state_->surface()));
- }
+ scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current = MakeCurrentIfNeeded();
+
+ // If we changed contexts, then we always want to restore it, since the caller
+ // doesn't know that we're switching contexts.
+ if (scoped_make_current)
+ mode = kDoRestoreBindings;
+
+ // Save the current binding if requested.
+ GLint bound_service_id = 0;
+ if (mode == kDoRestoreBindings)
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+
surface_texture_->UpdateTexImage();
+ if (mode == kDoRestoreBindings)
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
// Helpfully, this is already column major.
surface_texture_->GetTransformMatrix(gl_matrix_);
@@ -153,16 +173,19 @@ void AVDACodecImage::SetMediaCodec(media::MediaCodecBridge* codec) {
media_codec_ = codec;
}
-void AVDACodecImage::setTexture(gpu::gles2::Texture* texture) {
+void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) {
texture_ = texture;
}
void AVDACodecImage::AttachSurfaceTextureToContext() {
+ DCHECK(surface_texture_);
+
+ // We assume that the currently bound texture is the intended one.
+
// Attach the surface texture to the first context we're bound on, so that
// no context switch is needed later.
-
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -170,35 +193,48 @@ void AVDACodecImage::AttachSurfaceTextureToContext() {
// We could do this earlier, but SurfaceTexture has context affinity, and we
// don't want to require a context switch.
surface_texture_->AttachToGLContext();
- shared_state_->did_attach_surface_texture();
-}
-
-void AVDACodecImage::InstallTextureMatrix() {
- // glUseProgram() has been run already -- just modify the uniform.
- // Updating this via VideoFrameProvider::Client::DidUpdateMatrix() would
- // be a better solution, except that we'd definitely miss a frame at this
- // point in drawing.
- // Our current method assumes that we'll end up being a stream resource,
- // and that the program has a texMatrix uniform that does what we want.
- if (need_shader_info_) {
- GLint program_id = -1;
- glGetIntegerv(GL_CURRENT_PROGRAM, &program_id);
-
- if (program_id >= 0) {
- // This is memorized from cc/output/shader.cc .
- const char* uniformName = "texMatrix";
- texmatrix_uniform_location_ =
- glGetUniformLocation(program_id, uniformName);
- DCHECK(texmatrix_uniform_location_ != -1);
- }
+ shared_state_->DidAttachSurfaceTexture();
+}
- // Only try once.
- need_shader_info_ = false;
+scoped_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() {
+ DCHECK(shared_state_->context());
+ scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
+ if (!shared_state_->context()->IsCurrent(NULL)) {
+ scoped_make_current.reset(new ui::ScopedMakeCurrent(
+ shared_state_->context(), shared_state_->surface()));
}
- if (texmatrix_uniform_location_ >= 0) {
- glUniformMatrix4fv(texmatrix_uniform_location_, 1, false, gl_matrix_);
+ return scoped_make_current;
+}
+
+void AVDACodecImage::GetTextureMatrix(float matrix[16]) {
+ if (IsCodecBufferOutstanding() && shared_state_ && surface_texture_) {
+ // Our current matrix may be stale. Update it if possible.
+ if (!shared_state_->surface_texture_is_attached()) {
+ // Don't attach the surface texture permanently. Perhaps we should
+ // just attach the surface texture in avda and be done with it.
+ GLuint service_id = 0;
+ glGenTextures(1, &service_id);
+ GLint bound_service_id = 0;
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
+ AttachSurfaceTextureToContext();
+ UpdateSurfaceTexture(kDontRestoreBindings);
+ // Detach the surface texture, which deletes the generated texture.
+ surface_texture_->DetachFromGLContext();
+ shared_state_->DidDetachSurfaceTexture();
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
+ } else {
+ // Surface texture is already attached, so just update it.
+ UpdateSurfaceTexture(kDoRestoreBindings);
+ }
}
+
+ memcpy(matrix, gl_matrix_, sizeof(gl_matrix_));
+}
+
+bool AVDACodecImage::IsCodecBufferOutstanding() const {
+ return codec_buffer_index_ != kInvalidCodecBufferIndex && media_codec_;
}
} // namespace content
diff --git a/chromium/content/common/gpu/media/avda_codec_image.h b/chromium/content/common/gpu/media/avda_codec_image.h
index ef0456a9fba..46547e478c8 100644
--- a/chromium/content/common/gpu/media/avda_codec_image.h
+++ b/chromium/content/common/gpu/media/avda_codec_image.h
@@ -9,13 +9,17 @@
#include "base/macros.h"
#include "content/common/gpu/media/avda_shared_state.h"
-#include "ui/gl/gl_image.h"
+#include "gpu/command_buffer/service/gl_stream_texture_image.h"
+
+namespace ui {
+class ScopedMakeCurrent;
+}
namespace content {
-// GLImage that renders MediaCodec buffers to a SurfaceTexture as needed
-// in order to draw them.
-class AVDACodecImage : public gl::GLImage {
+// GLImage that renders MediaCodec buffers to a SurfaceTexture or SurfaceView as
+// needed in order to draw them.
+class AVDACodecImage : public gpu::gles2::GLStreamTextureImage {
public:
AVDACodecImage(const scoped_refptr<AVDASharedState>&,
media::VideoCodecBridge* codec,
@@ -44,6 +48,8 @@ class AVDACodecImage : public gl::GLImage {
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
const std::string& dump_name) override;
+ // gpu::gles2::GLStreamTextureMatrix implementation
+ void GetTextureMatrix(float xform[16]) override;
public:
// Decoded buffer index that has the image for us to display.
@@ -58,24 +64,42 @@ class AVDACodecImage : public gl::GLImage {
void SetMediaCodec(media::MediaCodecBridge* codec);
- void setTexture(gpu::gles2::Texture* texture);
+ void SetTexture(gpu::gles2::Texture* texture);
private:
- // Make sure that the surface texture's front buffer is current.
- void UpdateSurfaceTexture();
-
- // Attach the surface texture to our GL context, with a texture that we
- // create for it.
+ enum { kInvalidCodecBufferIndex = -1 };
+
+ // Make sure that the surface texture's front buffer is current. This will
+ // save / restore the current context. It will optionally restore the texture
+ // bindings in the surface texture's context, based on |mode|. This is
+ // intended as a hint if we don't need to change contexts. If we do need to
+ // change contexts, then we'll always preserve the texture bindings in the
+ // both contexts. In other words, the caller is telling us whether it's
+ // okay to change the binding in the current context.
+ enum RestoreBindingsMode { kDontRestoreBindings, kDoRestoreBindings };
+ void UpdateSurfaceTexture(RestoreBindingsMode mode);
+
+ // Attach the surface texture to our GL context to whatever texture is bound
+ // on the active unit.
void AttachSurfaceTextureToContext();
- // Install the current texture matrix into the shader.
- void InstallTextureMatrix();
+ // Make shared_state_->context() current if it isn't already.
+ scoped_ptr<ui::ScopedMakeCurrent> MakeCurrentIfNeeded();
+
+ // Return whether or not the current context is in the same share group as
+ // |surface_texture_|'s client texture.
+ // TODO(liberato): is this needed?
+ bool IsCorrectShareGroup() const;
+
+ // Return whether there is a codec buffer that we haven't rendered yet. Will
+ // return false also if there's no codec or we otherwise can't update.
+ bool IsCodecBufferOutstanding() const;
// Shared state between the AVDA and all AVDACodecImages.
scoped_refptr<AVDASharedState> shared_state_;
- // Codec's buffer index that we should render to the surface texture,
- // or <0 if none.
+ // The MediaCodec buffer index that we should render. Only valid if not equal
+ // to |kInvalidCodecBufferIndex|.
int codec_buffer_index_;
// Our image size.
@@ -86,6 +110,8 @@ class AVDACodecImage : public gl::GLImage {
const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder_;
+ // The SurfaceTexture to render to. This is null when rendering to a
+ // SurfaceView.
const scoped_refptr<gfx::SurfaceTexture> surface_texture_;
// Should we detach |surface_texture_| from its GL context when we are
@@ -95,12 +121,6 @@ class AVDACodecImage : public gl::GLImage {
// The texture that we're attached to.
gpu::gles2::Texture* texture_;
- // Have we cached |texmatrix_uniform_location_| yet?
- bool need_shader_info_;
-
- // Uniform ID of the texture matrix in the shader.
- GLint texmatrix_uniform_location_;
-
// Texture matrix of the front buffer of the surface texture.
float gl_matrix_[16];
diff --git a/chromium/content/common/gpu/media/avda_shared_state.cc b/chromium/content/common/gpu/media/avda_shared_state.cc
index c182bf05385..7746254fee9 100644
--- a/chromium/content/common/gpu/media/avda_shared_state.cc
+++ b/chromium/content/common/gpu/media/avda_shared_state.cc
@@ -4,6 +4,7 @@
#include "content/common/gpu/media/avda_shared_state.h"
+#include "base/time/time.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/scoped_make_current.h"
@@ -21,10 +22,13 @@ void AVDASharedState::SignalFrameAvailable() {
}
void AVDASharedState::WaitForFrameAvailable() {
- frame_available_event_.Wait();
+ // 10msec covers >99.9% of cases, so just wait for up to that much before
+ // giving up. If an error occurs, we might not ever get a notification.
+ const base::TimeDelta max_wait_time(base::TimeDelta::FromMilliseconds(10));
+ frame_available_event_.TimedWait(max_wait_time);
}
-void AVDASharedState::did_attach_surface_texture() {
+void AVDASharedState::DidAttachSurfaceTexture() {
context_ = gfx::GLContext::GetCurrent();
surface_ = gfx::GLSurface::GetCurrent();
DCHECK(context_);
@@ -33,4 +37,10 @@ void AVDASharedState::did_attach_surface_texture() {
surface_texture_is_attached_ = true;
}
+void AVDASharedState::DidDetachSurfaceTexture() {
+ context_ = nullptr;
+ surface_ = nullptr;
+ surface_texture_is_attached_ = false;
+}
+
} // namespace content
diff --git a/chromium/content/common/gpu/media/avda_shared_state.h b/chromium/content/common/gpu/media/avda_shared_state.h
index eb62681fcd5..5f80c44d729 100644
--- a/chromium/content/common/gpu/media/avda_shared_state.h
+++ b/chromium/content/common/gpu/media/avda_shared_state.h
@@ -50,10 +50,19 @@ class AVDASharedState : public base::RefCounted<AVDASharedState> {
return surface_texture_is_attached_;
}
+ // TODO(liberato): move the surface texture here and make these calls
+ // attach / detach it also. There are several changes going on in avda
+ // concurrently, so I don't want to change that until the dust settles.
+ // AVDACodecImage would no longer hold the surface texture.
+
// Call this when the SurfaceTexture is attached to a GL context. This will
// update surface_texture_is_attached(), and set the context() and surface()
// to match.
- void did_attach_surface_texture();
+ void DidAttachSurfaceTexture();
+
+ // Call this when the SurfaceTexture is detached from its GL context. This
+ // will cause us to forget the last binding.
+ void DidDetachSurfaceTexture();
private:
// Platform gl texture Id for |surface_texture_|. This will be zero if
diff --git a/chromium/content/common/gpu/media/avda_state_provider.h b/chromium/content/common/gpu/media/avda_state_provider.h
index 2c84f2ed04a..e7dfac62ded 100644
--- a/chromium/content/common/gpu/media/avda_state_provider.h
+++ b/chromium/content/common/gpu/media/avda_state_provider.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
+#include "gpu/command_buffer/service/texture_manager.h"
#include "media/video/video_decode_accelerator.h"
namespace gfx {
@@ -36,6 +37,8 @@ class AVDAStateProvider {
virtual const gfx::Size& GetSize() const = 0;
virtual const base::ThreadChecker& ThreadChecker() const = 0;
virtual base::WeakPtr<gpu::gles2::GLES2Decoder> GetGlDecoder() const = 0;
+ virtual gpu::gles2::TextureRef* GetTextureForPicture(
+ const media::PictureBuffer& picture_buffer) = 0;
// Helper function to report an error condition and stop decoding.
// This will post NotifyError(), and transition to the error state.
diff --git a/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.cc b/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
index 40a3239cb25..e55c9009720 100644
--- a/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
+++ b/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.cc
@@ -21,7 +21,6 @@
#include "base/base_paths_win.h"
#include "base/bind.h"
#include "base/callback.h"
-#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
@@ -34,15 +33,14 @@
#include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h"
#include "build/build_config.h"
-#include "content/public/common/content_switches.h"
#include "media/base/win/mf_initializer.h"
#include "media/video/video_decode_accelerator.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_surface_egl.h"
-#include "ui/gl/gl_switches.h"
namespace {
@@ -113,6 +111,91 @@ DEFINE_GUID(CLSID_VideoProcessorMFT,
DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12,
0xcf, 0x3e, 0x23, 0x8a, 0xcc, 0xe9);
+// Defines the GUID for the Intel H264 DXVA device.
+static const GUID DXVA2_Intel_ModeH264_E = {
+ 0x604F8E68, 0x4951, 0x4c54,{ 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6}
+};
+
+// R600, R700, Evergreen and Cayman AMD cards. These support DXVA via UVD3
+// or earlier, and don't handle resolutions higher than 1920 x 1088 well.
+static const DWORD g_AMDUVD3GPUList[] = {
+ 0x9400, 0x9401, 0x9402, 0x9403, 0x9405, 0x940a, 0x940b, 0x940f, 0x94c0,
+ 0x94c1, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, 0x94c9, 0x94cb,
+ 0x94cc, 0x94cd, 0x9580, 0x9581, 0x9583, 0x9586, 0x9587, 0x9588, 0x9589,
+ 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9500, 0x9501, 0x9504,
+ 0x9505, 0x9506, 0x9507, 0x9508, 0x9509, 0x950f, 0x9511, 0x9515, 0x9517,
+ 0x9519, 0x95c0, 0x95c2, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c9, 0x95cc,
+ 0x95cd, 0x95ce, 0x95cf, 0x9590, 0x9591, 0x9593, 0x9595, 0x9596, 0x9597,
+ 0x9598, 0x9599, 0x959b, 0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615,
+ 0x9616, 0x9710, 0x9711, 0x9712, 0x9713, 0x9714, 0x9715, 0x9440, 0x9441,
+ 0x9442, 0x9443, 0x9444, 0x9446, 0x944a, 0x944b, 0x944c, 0x944e, 0x9450,
+ 0x9452, 0x9456, 0x945a, 0x945b, 0x945e, 0x9460, 0x9462, 0x946a, 0x946b,
+ 0x947a, 0x947b, 0x9480, 0x9487, 0x9488, 0x9489, 0x948a, 0x948f, 0x9490,
+ 0x9491, 0x9495, 0x9498, 0x949c, 0x949e, 0x949f, 0x9540, 0x9541, 0x9542,
+ 0x954e, 0x954f, 0x9552, 0x9553, 0x9555, 0x9557, 0x955f, 0x94a0, 0x94a1,
+ 0x94a3, 0x94b1, 0x94b3, 0x94b4, 0x94b5, 0x94b9, 0x68e0, 0x68e1, 0x68e4,
+ 0x68e5, 0x68e8, 0x68e9, 0x68f1, 0x68f2, 0x68f8, 0x68f9, 0x68fa, 0x68fe,
+ 0x68c0, 0x68c1, 0x68c7, 0x68c8, 0x68c9, 0x68d8, 0x68d9, 0x68da, 0x68de,
+ 0x68a0, 0x68a1, 0x68a8, 0x68a9, 0x68b0, 0x68b8, 0x68b9, 0x68ba, 0x68be,
+ 0x68bf, 0x6880, 0x6888, 0x6889, 0x688a, 0x688c, 0x688d, 0x6898, 0x6899,
+ 0x689b, 0x689e, 0x689c, 0x689d, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806,
+ 0x9807, 0x9808, 0x9809, 0x980a, 0x9640, 0x9641, 0x9647, 0x9648, 0x964a,
+ 0x964b, 0x964c, 0x964e, 0x964f, 0x9642, 0x9643, 0x9644, 0x9645, 0x9649,
+ 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728,
+ 0x6729, 0x6738, 0x6739, 0x673e, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744,
+ 0x6745, 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x6750, 0x6751, 0x6758,
+ 0x6759, 0x675b, 0x675d, 0x675f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6849,
+ 0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765,
+ 0x6766, 0x6767, 0x6768, 0x6770, 0x6771, 0x6772, 0x6778, 0x6779, 0x677b,
+ 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 0x6708,
+ 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x683D, 0x9900, 0x9901,
+ 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, 0x9908, 0x9909, 0x990a, 0x990b,
+ 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918, 0x9919,
+ 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998,
+ 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4,
+};
+
+// Legacy Intel GPUs (Second generation) which have trouble with resolutions
+// higher than 1920 x 1088
+static const DWORD g_IntelLegacyGPUList[] = {
+ 0x102, 0x106, 0x116, 0x126,
+};
+
+// Provides scoped access to the underlying buffer in an IMFMediaBuffer
+// instance.
+class MediaBufferScopedPointer {
+ public:
+ MediaBufferScopedPointer(IMFMediaBuffer* media_buffer)
+ : media_buffer_(media_buffer),
+ buffer_(nullptr),
+ max_length_(0),
+ current_length_(0) {
+ HRESULT hr = media_buffer_->Lock(&buffer_, &max_length_, &current_length_);
+ CHECK(SUCCEEDED(hr));
+ }
+
+ ~MediaBufferScopedPointer() {
+ HRESULT hr = media_buffer_->Unlock();
+ CHECK(SUCCEEDED(hr));
+ }
+
+ uint8_t* get() {
+ return buffer_;
+ }
+
+ DWORD current_length() const {
+ return current_length_;
+ }
+
+ private:
+ base::win::ScopedComPtr<IMFMediaBuffer> media_buffer_;
+ uint8_t* buffer_;
+ DWORD max_length_;
+ DWORD current_length_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaBufferScopedPointer);
+};
+
} // namespace
namespace content {
@@ -122,7 +205,10 @@ static const media::VideoCodecProfile kSupportedProfiles[] = {
media::H264PROFILE_MAIN,
media::H264PROFILE_HIGH,
media::VP8PROFILE_ANY,
- media::VP9PROFILE_ANY
+ media::VP9PROFILE_PROFILE0,
+ media::VP9PROFILE_PROFILE1,
+ media::VP9PROFILE_PROFILE2,
+ media::VP9PROFILE_PROFILE3
};
CreateDXGIDeviceManager DXVAVideoDecodeAccelerator::create_dxgi_device_manager_
@@ -162,10 +248,16 @@ enum {
kFlushDecoderSurfaceTimeoutMs = 1,
// Maximum iterations where we try to flush the d3d device.
kMaxIterationsForD3DFlush = 4,
+ // Maximum iterations where we try to flush the ANGLE device before reusing
+ // the texture.
+ kMaxIterationsForANGLEReuseFlush = 16,
// We only request 5 picture buffers from the client which are used to hold
// the decoded samples. These buffers are then reused when the client tells
// us that it is done with the buffer.
kNumPictureBuffers = 5,
+ // The keyed mutex should always be released before the other thread
+ // attempts to acquire it, so AcquireSync should always return immediately.
+ kAcquireSyncWaitMs = 0,
};
static IMFSample* CreateEmptySample() {
@@ -177,8 +269,9 @@ static IMFSample* CreateEmptySample() {
// Creates a Media Foundation sample with one buffer of length |buffer_length|
// on a |align|-byte boundary. Alignment must be a perfect power of 2 or 0.
-static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) {
- CHECK_GT(buffer_length, 0);
+static IMFSample* CreateEmptySampleWithBuffer(uint32_t buffer_length,
+ int align) {
+ CHECK_GT(buffer_length, 0U);
base::win::ScopedComPtr<IMFSample> sample;
sample.Attach(CreateEmptySample());
@@ -209,11 +302,11 @@ static IMFSample* CreateEmptySampleWithBuffer(int buffer_length, int align) {
// |min_size| specifies the minimum size of the buffer (might be required by
// the decoder for input). If no alignment is required, provide 0.
static IMFSample* CreateInputSample(const uint8_t* stream,
- int size,
- int min_size,
+ uint32_t size,
+ uint32_t min_size,
int alignment) {
CHECK(stream);
- CHECK_GT(size, 0);
+ CHECK_GT(size, 0U);
base::win::ScopedComPtr<IMFSample> sample;
sample.Attach(CreateEmptySampleWithBuffer(std::max(min_size, size),
alignment));
@@ -230,28 +323,16 @@ static IMFSample* CreateInputSample(const uint8_t* stream,
RETURN_ON_HR_FAILURE(hr, "Failed to lock buffer", NULL);
CHECK_EQ(current_length, 0u);
- CHECK_GE(static_cast<int>(max_length), size);
+ CHECK_GE(max_length, size);
memcpy(destination, stream, size);
- hr = buffer->Unlock();
- RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL);
-
hr = buffer->SetCurrentLength(size);
RETURN_ON_HR_FAILURE(hr, "Failed to set buffer length", NULL);
- return sample.Detach();
-}
-
-static IMFSample* CreateSampleFromInputBuffer(
- const media::BitstreamBuffer& bitstream_buffer,
- DWORD stream_size,
- DWORD alignment) {
- base::SharedMemory shm(bitstream_buffer.handle(), true);
- RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()),
- "Failed in base::SharedMemory::Map", NULL);
+ hr = buffer->Unlock();
+ RETURN_ON_HR_FAILURE(hr, "Failed to unlock buffer", NULL);
- return CreateInputSample(reinterpret_cast<const uint8_t*>(shm.memory()),
- bitstream_buffer.size(), stream_size, alignment);
+ return sample.Detach();
}
// Helper function to create a COM object instance from a DLL. The alternative
@@ -289,55 +370,188 @@ template<class T>
base::win::ScopedComPtr<T> QueryDeviceObjectFromANGLE(int object_type) {
base::win::ScopedComPtr<T> device_object;
- EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
+ EGLDisplay egl_display = nullptr;
intptr_t egl_device = 0;
intptr_t device = 0;
+ {
+ TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. GetHardwareDisplay");
+ egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
+ }
+
RETURN_ON_FAILURE(
gfx::GLSurfaceEGL::HasEGLExtension("EGL_EXT_device_query"),
"EGL_EXT_device_query missing",
device_object);
- PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT =
- reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(eglGetProcAddress(
- "eglQueryDisplayAttribEXT"));
+ PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT = nullptr;
- RETURN_ON_FAILURE(
- QueryDisplayAttribEXT,
- "Failed to get the eglQueryDisplayAttribEXT function from ANGLE",
- device_object);
+ {
+ TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress");
- PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT =
- reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(eglGetProcAddress(
- "eglQueryDeviceAttribEXT"));
+ QueryDisplayAttribEXT =
+ reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(eglGetProcAddress(
+ "eglQueryDisplayAttribEXT"));
- RETURN_ON_FAILURE(
- QueryDeviceAttribEXT,
- "Failed to get the eglQueryDeviceAttribEXT function from ANGLE",
- device_object);
+ RETURN_ON_FAILURE(
+ QueryDisplayAttribEXT,
+ "Failed to get the eglQueryDisplayAttribEXT function from ANGLE",
+ device_object);
+ }
- RETURN_ON_FAILURE(
- QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device),
- "The eglQueryDisplayAttribEXT function failed to get the EGL device",
- device_object);
+ PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT = nullptr;
+
+ {
+ TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. eglGetProcAddress");
+
+ QueryDeviceAttribEXT =
+ reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(eglGetProcAddress(
+ "eglQueryDeviceAttribEXT"));
+
+ RETURN_ON_FAILURE(
+ QueryDeviceAttribEXT,
+ "Failed to get the eglQueryDeviceAttribEXT function from ANGLE",
+ device_object);
+ }
+
+ {
+ TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT");
+
+ RETURN_ON_FAILURE(
+ QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device),
+ "The eglQueryDisplayAttribEXT function failed to get the EGL device",
+ device_object);
+ }
RETURN_ON_FAILURE(
egl_device,
"Failed to get the EGL device",
device_object);
- RETURN_ON_FAILURE(
- QueryDeviceAttribEXT(
- reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device),
- "The eglQueryDeviceAttribEXT function failed to get the device",
- device_object);
+ {
+ TRACE_EVENT0("gpu", "QueryDeviceObjectFromANGLE. QueryDisplayAttribEXT");
- RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object);
+ RETURN_ON_FAILURE(
+ QueryDeviceAttribEXT(
+ reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device),
+ "The eglQueryDeviceAttribEXT function failed to get the device",
+ device_object);
+
+ RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object);
+ }
device_object = reinterpret_cast<T*>(device);
return device_object;
}
+H264ConfigChangeDetector::H264ConfigChangeDetector()
+ : last_sps_id_(0),
+ last_pps_id_(0),
+ config_changed_(false),
+ pending_config_changed_(false) {
+}
+
+H264ConfigChangeDetector::~H264ConfigChangeDetector() {
+}
+
+bool H264ConfigChangeDetector::DetectConfig(const uint8_t* stream,
+ unsigned int size) {
+ std::vector<uint8_t> sps;
+ std::vector<uint8_t> pps;
+ media::H264NALU nalu;
+ bool idr_seen = false;
+
+ if (!parser_.get())
+ parser_.reset(new media::H264Parser);
+
+ parser_->SetStream(stream, size);
+ config_changed_ = false;
+
+ while (true) {
+ media::H264Parser::Result result = parser_->AdvanceToNextNALU(&nalu);
+
+ if (result == media::H264Parser::kEOStream)
+ break;
+
+ if (result == media::H264Parser::kUnsupportedStream) {
+ DLOG(ERROR) << "Unsupported H.264 stream";
+ return false;
+ }
+
+ if (result != media::H264Parser::kOk) {
+ DLOG(ERROR) << "Failed to parse H.264 stream";
+ return false;
+ }
+
+ switch (nalu.nal_unit_type) {
+ case media::H264NALU::kSPS:
+ result = parser_->ParseSPS(&last_sps_id_);
+ if (result == media::H264Parser::kUnsupportedStream) {
+ DLOG(ERROR) << "Unsupported SPS";
+ return false;
+ }
+
+ if (result != media::H264Parser::kOk) {
+ DLOG(ERROR) << "Could not parse SPS";
+ return false;
+ }
+
+ sps.assign(nalu.data, nalu.data + nalu.size);
+ break;
+
+ case media::H264NALU::kPPS:
+ result = parser_->ParsePPS(&last_pps_id_);
+ if (result == media::H264Parser::kUnsupportedStream) {
+ DLOG(ERROR) << "Unsupported PPS";
+ return false;
+ }
+ if (result != media::H264Parser::kOk) {
+ DLOG(ERROR) << "Could not parse PPS";
+ return false;
+ }
+ pps.assign(nalu.data, nalu.data + nalu.size);
+ break;
+
+ case media::H264NALU::kIDRSlice:
+ idr_seen = true;
+ // If we previously detected a configuration change, and see an IDR
+ // slice next time around, we need to flag a configuration change.
+ if (pending_config_changed_) {
+ config_changed_ = true;
+ pending_config_changed_ = false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!sps.empty() && sps != last_sps_) {
+ if (!last_sps_.empty()) {
+ // Flag configuration changes after we see an IDR slice.
+ if (idr_seen) {
+ config_changed_ = true;
+ } else {
+ pending_config_changed_ = true;
+ }
+ }
+ last_sps_.swap(sps);
+ }
+
+ if (!pps.empty() && pps != last_pps_) {
+ if (!last_pps_.empty()) {
+ // Flag configuration changes after we see an IDR slice.
+ if (idr_seen) {
+ config_changed_ = true;
+ } else {
+ pending_config_changed_ = true;
+ }
+ }
+ last_pps_.swap(pps);
+ }
+ return true;
+}
// Maintains information about a DXVA picture buffer, i.e. whether it is
// available for rendering, the texture information, etc.
@@ -349,7 +563,11 @@ struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
EGLConfig egl_config);
~DXVAPictureBuffer();
- void ReusePictureBuffer();
+ bool InitializeTexture(const DXVAVideoDecodeAccelerator& decoder,
+ bool use_rgb);
+
+ bool ReusePictureBuffer();
+ void ResetReuseFence();
// Copies the output sample data to the picture buffer provided by the
// client.
// The dest_surface parameter contains the decoded bits.
@@ -375,20 +593,37 @@ struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
return picture_buffer_.size();
}
+ bool waiting_to_reuse() const { return waiting_to_reuse_; }
+
+ gfx::GLFence* reuse_fence() { return reuse_fence_.get(); }
+
// Called when the source surface |src_surface| is copied to the destination
// |dest_surface|
- void CopySurfaceComplete(IDirect3DSurface9* src_surface,
+ bool CopySurfaceComplete(IDirect3DSurface9* src_surface,
IDirect3DSurface9* dest_surface);
private:
explicit DXVAPictureBuffer(const media::PictureBuffer& buffer);
bool available_;
+
+ // This is true if the decoder is currently waiting on the fence before
+ // reusing the buffer.
+ bool waiting_to_reuse_;
media::PictureBuffer picture_buffer_;
EGLSurface decoding_surface_;
+ scoped_ptr<gfx::GLFence> reuse_fence_;
+
+ HANDLE texture_share_handle_;
base::win::ScopedComPtr<IDirect3DTexture9> decoding_texture_;
base::win::ScopedComPtr<ID3D11Texture2D> dx11_decoding_texture_;
+ base::win::ScopedComPtr<IDXGIKeyedMutex> egl_keyed_mutex_;
+ base::win::ScopedComPtr<IDXGIKeyedMutex> dx11_keyed_mutex_;
+
+ // This is the last value that was used to release the keyed mutex.
+ uint64_t keyed_mutex_value_;
+
// The following |IDirect3DSurface9| interface pointers are used to hold
// references on the surfaces during the course of a StretchRect operation
// to copy the source surface to the target. The references are released
@@ -422,6 +657,9 @@ DXVAVideoDecodeAccelerator::DXVAPictureBuffer::Create(
eglGetConfigAttrib(egl_display, egl_config, EGL_BIND_TO_TEXTURE_RGB,
&use_rgb);
+ if (!picture_buffer->InitializeTexture(decoder, !!use_rgb))
+ return linked_ptr<DXVAPictureBuffer>(nullptr);
+
EGLint attrib_list[] = {
EGL_WIDTH, buffer.size().width(),
EGL_HEIGHT, buffer.size().height(),
@@ -430,59 +668,84 @@ DXVAVideoDecodeAccelerator::DXVAPictureBuffer::Create(
EGL_NONE
};
- picture_buffer->decoding_surface_ = eglCreatePbufferSurface(
- egl_display,
- egl_config,
- attrib_list);
+ picture_buffer->decoding_surface_ = eglCreatePbufferFromClientBuffer(
+ egl_display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
+ picture_buffer->texture_share_handle_, egl_config, attrib_list);
RETURN_ON_FAILURE(picture_buffer->decoding_surface_,
"Failed to create surface",
linked_ptr<DXVAPictureBuffer>(NULL));
+ if (decoder.d3d11_device_ && decoder.use_keyed_mutex_) {
+ void* keyed_mutex = nullptr;
+ EGLBoolean ret = eglQuerySurfacePointerANGLE(
+ egl_display, picture_buffer->decoding_surface_,
+ EGL_DXGI_KEYED_MUTEX_ANGLE, &keyed_mutex);
+ RETURN_ON_FAILURE(keyed_mutex && ret == EGL_TRUE,
+ "Failed to query ANGLE keyed mutex",
+ linked_ptr<DXVAPictureBuffer>(nullptr));
+ picture_buffer->egl_keyed_mutex_ = base::win::ScopedComPtr<IDXGIKeyedMutex>(
+ static_cast<IDXGIKeyedMutex*>(keyed_mutex));
+ }
+ picture_buffer->use_rgb_ = !!use_rgb;
+ return picture_buffer;
+}
- HANDLE share_handle = NULL;
- EGLBoolean ret = eglQuerySurfacePointerANGLE(
- egl_display,
- picture_buffer->decoding_surface_,
- EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
- &share_handle);
+bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::InitializeTexture(
+ const DXVAVideoDecodeAccelerator& decoder,
+ bool use_rgb) {
+ DCHECK(!texture_share_handle_);
+ if (decoder.d3d11_device_) {
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = picture_buffer_.size().width();
+ desc.Height = picture_buffer_.size().height();
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = decoder.use_keyed_mutex_
+ ? D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
+ : D3D11_RESOURCE_MISC_SHARED;
+
+ HRESULT hr = decoder.d3d11_device_->CreateTexture2D(
+ &desc, nullptr, dx11_decoding_texture_.Receive());
+ RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false);
+ if (decoder.use_keyed_mutex_) {
+ hr = dx11_keyed_mutex_.QueryFrom(dx11_decoding_texture_.get());
+ RETURN_ON_HR_FAILURE(hr, "Failed to get keyed mutex", false);
+ }
- RETURN_ON_FAILURE(share_handle && ret == EGL_TRUE,
- "Failed to query ANGLE surface pointer",
- linked_ptr<DXVAPictureBuffer>(NULL));
+ base::win::ScopedComPtr<IDXGIResource> resource;
+ hr = resource.QueryFrom(dx11_decoding_texture_.get());
+ DCHECK(SUCCEEDED(hr));
+ hr = resource->GetSharedHandle(&texture_share_handle_);
+ RETURN_ON_FAILURE(SUCCEEDED(hr) && texture_share_handle_,
+ "Failed to query shared handle", false);
- HRESULT hr = E_FAIL;
- if (decoder.d3d11_device_) {
- base::win::ScopedComPtr<ID3D11Resource> resource;
- hr = decoder.d3d11_device_->OpenSharedResource(
- share_handle,
- __uuidof(ID3D11Resource),
- reinterpret_cast<void**>(resource.Receive()));
- RETURN_ON_HR_FAILURE(hr, "Failed to open shared resource",
- linked_ptr<DXVAPictureBuffer>(NULL));
- hr = picture_buffer->dx11_decoding_texture_.QueryFrom(resource.get());
} else {
+ HRESULT hr = E_FAIL;
hr = decoder.d3d9_device_ex_->CreateTexture(
- buffer.size().width(),
- buffer.size().height(),
- 1,
- D3DUSAGE_RENDERTARGET,
- use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
- D3DPOOL_DEFAULT,
- picture_buffer->decoding_texture_.Receive(),
- &share_handle);
- }
- RETURN_ON_HR_FAILURE(hr, "Failed to create texture",
- linked_ptr<DXVAPictureBuffer>(NULL));
- picture_buffer->use_rgb_ = !!use_rgb;
- return picture_buffer;
+ picture_buffer_.size().width(), picture_buffer_.size().height(), 1,
+ D3DUSAGE_RENDERTARGET, use_rgb ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
+ D3DPOOL_DEFAULT, decoding_texture_.Receive(), &texture_share_handle_);
+ RETURN_ON_HR_FAILURE(hr, "Failed to create texture", false);
+ RETURN_ON_FAILURE(texture_share_handle_, "Failed to query shared handle",
+ false);
+ }
+ return true;
}
DXVAVideoDecodeAccelerator::DXVAPictureBuffer::DXVAPictureBuffer(
const media::PictureBuffer& buffer)
: available_(true),
+ waiting_to_reuse_(false),
picture_buffer_(buffer),
decoding_surface_(NULL),
- use_rgb_(true) {
-}
+ texture_share_handle_(nullptr),
+ keyed_mutex_value_(0),
+ use_rgb_(true) {}
DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() {
if (decoding_surface_) {
@@ -500,7 +763,7 @@ DXVAVideoDecodeAccelerator::DXVAPictureBuffer::~DXVAPictureBuffer() {
}
}
-void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
+bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
DCHECK(decoding_surface_);
EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
eglReleaseTexImage(
@@ -510,7 +773,21 @@ void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ReusePictureBuffer() {
decoder_surface_.Release();
target_surface_.Release();
decoder_dx11_texture_.Release();
+ waiting_to_reuse_ = false;
set_available(true);
+ if (egl_keyed_mutex_) {
+ HRESULT hr = egl_keyed_mutex_->ReleaseSync(++keyed_mutex_value_);
+ RETURN_ON_FAILURE(hr == S_OK, "Could not release sync mutex", false);
+ }
+ return true;
+}
+
+void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::ResetReuseFence() {
+ if (!reuse_fence_ || !reuse_fence_->ResetSupported())
+ reuse_fence_.reset(gfx::GLFence::Create());
+ else
+ reuse_fence_->ResetState();
+ waiting_to_reuse_ = true;
}
bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::
@@ -525,8 +802,9 @@ bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::
// when we receive a notification that the copy was completed or when the
// DXVAPictureBuffer instance is destroyed.
decoder_dx11_texture_ = dx11_texture;
- decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(), NULL,
- id(), input_buffer_id);
+ decoder->CopyTexture(dx11_texture, dx11_decoding_texture_.get(),
+ dx11_keyed_mutex_, keyed_mutex_value_, NULL, id(),
+ input_buffer_id);
return true;
}
D3DSURFACE_DESC surface_desc;
@@ -566,7 +844,7 @@ bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::
return true;
}
-void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete(
+bool DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete(
IDirect3DSurface9* src_surface,
IDirect3DSurface9* dest_surface) {
DCHECK(!available());
@@ -574,7 +852,7 @@ void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete(
GLint current_texture = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
- glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id());
+ glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_ids()[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -587,6 +865,12 @@ void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete(
DCHECK(decoder_dx11_texture_.get());
decoder_dx11_texture_.Release();
}
+ if (egl_keyed_mutex_) {
+ keyed_mutex_value_++;
+ HRESULT result =
+ egl_keyed_mutex_->AcquireSync(keyed_mutex_value_, kAcquireSyncWaitMs);
+ RETURN_ON_FAILURE(result == S_OK, "Could not acquire sync mutex", false);
+ }
EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
eglBindTexImage(
@@ -596,6 +880,7 @@ void DXVAVideoDecodeAccelerator::DXVAPictureBuffer::CopySurfaceComplete(
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, current_texture);
+ return true;
}
DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
@@ -608,8 +893,9 @@ DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {}
DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- gfx::GLContext* gl_context)
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ bool enable_accelerated_vpx_decode)
: client_(NULL),
dev_manager_reset_token_(0),
dx11_dev_manager_reset_token_(0),
@@ -618,14 +904,16 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
pictures_requested_(false),
inputs_before_decode_(0),
sent_drain_message_(false),
- make_context_current_(make_context_current),
+ get_gl_context_cb_(get_gl_context_cb),
+ make_context_current_cb_(make_context_current_cb),
codec_(media::kUnknownVideoCodec),
decoder_thread_("DXVAVideoDecoderThread"),
pending_flush_(false),
use_dx11_(false),
+ use_keyed_mutex_(false),
dx11_video_format_converter_media_type_needs_init_(true),
- gl_context_(gl_context),
using_angle_device_(false),
+ enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode),
weak_this_factory_(this) {
weak_ptr_ = weak_this_factory_.GetWeakPtr();
memset(&input_stream_info_, 0, sizeof(input_stream_info_));
@@ -638,6 +926,11 @@ DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
Client* client) {
+ if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
if (config.is_encrypted) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -695,6 +988,10 @@ bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
PLATFORM_FAILURE,
false);
+ RETURN_AND_NOTIFY_ON_FAILURE(gfx::GLFence::IsSupported(),
+ "GL fences are unsupported", PLATFORM_FAILURE,
+ false);
+
State state = GetState();
RETURN_AND_NOTIFY_ON_FAILURE((state == kUninitialized),
"Initialize: invalid state: " << state, ILLEGAL_STATE, false);
@@ -717,6 +1014,10 @@ bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
"Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
PLATFORM_FAILURE, false);
+ config_ = config;
+
+ config_change_detector_.reset(new H264ConfigChangeDetector);
+
SetState(kNormal);
StartDecoderThread();
@@ -883,15 +1184,28 @@ void DXVAVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
+ // SharedMemory will take over the ownership of handle.
+ base::SharedMemory shm(bitstream_buffer.handle(), true);
+
State state = GetState();
RETURN_AND_NOTIFY_ON_FAILURE((state == kNormal || state == kStopped ||
state == kFlushing),
"Invalid state: " << state, ILLEGAL_STATE,);
+ if (bitstream_buffer.id() < 0) {
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ false, "Invalid bitstream_buffer, id: " << bitstream_buffer.id(),
+ INVALID_ARGUMENT, );
+ }
base::win::ScopedComPtr<IMFSample> sample;
- sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer,
- input_stream_info_.cbSize,
- input_stream_info_.cbAlignment));
+ RETURN_AND_NOTIFY_ON_FAILURE(shm.Map(bitstream_buffer.size()),
+ "Failed in base::SharedMemory::Map",
+ PLATFORM_FAILURE, );
+
+ sample.Attach(CreateInputSample(
+ reinterpret_cast<const uint8_t*>(shm.memory()), bitstream_buffer.size(),
+ std::min<uint32_t>(bitstream_buffer.size(), input_stream_info_.cbSize),
+ input_stream_info_.cbAlignment));
RETURN_AND_NOTIFY_ON_FAILURE(sample.get(), "Failed to create input sample",
PLATFORM_FAILURE, );
@@ -919,6 +1233,7 @@ void DXVAVideoDecodeAccelerator::AssignPictureBuffers(
// and mark these buffers as available for use.
for (size_t buffer_index = 0; buffer_index < buffers.size();
++buffer_index) {
+ DCHECK_LE(1u, buffers[buffer_index].texture_ids().size());
linked_ptr<DXVAPictureBuffer> picture_buffer =
DXVAPictureBuffer::Create(*this, buffers[buffer_index], egl_config_);
RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer.get(),
@@ -956,17 +1271,70 @@ void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
// us that we can now recycle this picture buffer, so if we were waiting to
// dispose of it we now can.
if (it == output_picture_buffers_.end()) {
- it = stale_output_picture_buffers_.find(picture_buffer_id);
- RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(),
- "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
- weak_this_factory_.GetWeakPtr(), picture_buffer_id));
+ if (!stale_output_picture_buffers_.empty()) {
+ it = stale_output_picture_buffers_.find(picture_buffer_id);
+ RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(),
+ "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,);
+ main_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
+ weak_this_factory_.GetWeakPtr(), picture_buffer_id));
+ }
+ return;
+ }
+
+ if (it->second->available() || it->second->waiting_to_reuse())
+ return;
+
+ if (use_keyed_mutex_ || using_angle_device_) {
+ RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(),
+ "Failed to reuse picture buffer",
+ PLATFORM_FAILURE, );
+
+ ProcessPendingSamples();
+ if (pending_flush_) {
+ decoder_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
+ base::Unretained(this)));
+ }
+ } else {
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+ it->second->ResetReuseFence();
+
+ WaitForOutputBuffer(picture_buffer_id, 0);
+ }
+}
+
+void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id,
+ int count) {
+ DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
+ OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
+ if (it == output_picture_buffers_.end())
+ return;
+
+ DXVAPictureBuffer* picture_buffer = it->second.get();
+
+ DCHECK(!picture_buffer->available());
+ DCHECK(picture_buffer->waiting_to_reuse());
+
+ gfx::GLFence* fence = picture_buffer->reuse_fence();
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+ if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) {
+ main_thread_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer,
+ weak_this_factory_.GetWeakPtr(),
+ picture_buffer_id, count + 1),
+ base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
return;
}
+ RETURN_AND_NOTIFY_ON_FAILURE(picture_buffer->ReusePictureBuffer(),
+ "Failed to reuse picture buffer",
+ PLATFORM_FAILURE, );
- it->second->ReusePictureBuffer();
ProcessPendingSamples();
if (pending_flush_) {
decoder_thread_task_runner_->PostTask(
@@ -1046,7 +1414,9 @@ void DXVAVideoDecodeAccelerator::Destroy() {
delete this;
}
-bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() {
+bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
return false;
}
@@ -1057,17 +1427,19 @@ GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const {
// static
media::VideoDecodeAccelerator::SupportedProfiles
DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::GetSupportedProfiles");
+
// TODO(henryhsu): Need to ensure the profiles are actually supported.
SupportedProfiles profiles;
for (const auto& supported_profile : kSupportedProfiles) {
+ std::pair<int, int> min_resolution = GetMinResolution(supported_profile);
+ std::pair<int, int> max_resolution = GetMaxResolution(supported_profile);
+
SupportedProfile profile;
profile.profile = supported_profile;
- // Windows Media Foundation H.264 decoding does not support decoding videos
- // with any dimension smaller than 48 pixels:
- // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
- profile.min_resolution.SetSize(48, 48);
- // Use 1088 to account for 16x16 macroblocks.
- profile.max_resolution.SetSize(1920, 1088);
+ profile.min_resolution.SetSize(min_resolution.first, min_resolution.second);
+ profile.max_resolution.SetSize(max_resolution.first, max_resolution.second);
profiles.push_back(profile);
}
return profiles;
@@ -1077,17 +1449,224 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles() {
void DXVAVideoDecodeAccelerator::PreSandboxInitialization() {
::LoadLibrary(L"MFPlat.dll");
::LoadLibrary(L"msmpeg2vdec.dll");
+ ::LoadLibrary(L"mf.dll");
+ ::LoadLibrary(L"dxva2.dll");
if (base::win::GetVersion() > base::win::VERSION_WIN7) {
LoadLibrary(L"msvproc.dll");
} else {
- LoadLibrary(L"dxva2.dll");
#if defined(ENABLE_DX11_FOR_WIN7)
LoadLibrary(L"mshtmlmedia.dll");
#endif
}
}
+// static
+std::pair<int, int> DXVAVideoDecodeAccelerator::GetMinResolution(
+ media::VideoCodecProfile profile) {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::GetMinResolution");
+ std::pair<int, int> min_resolution;
+ if (profile >= media::H264PROFILE_BASELINE &&
+ profile <= media::H264PROFILE_HIGH) {
+ // Windows Media Foundation H.264 decoding does not support decoding videos
+ // with any dimension smaller than 48 pixels:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
+ min_resolution = std::make_pair(48, 48);
+ } else {
+ // TODO(ananta)
+ // Detect this properly for VP8/VP9 profiles.
+ min_resolution = std::make_pair(16, 16);
+ }
+ return min_resolution;
+}
+
+// static
+std::pair<int, int> DXVAVideoDecodeAccelerator::GetMaxResolution(
+ const media::VideoCodecProfile profile) {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::GetMaxResolution");
+ std::pair<int, int> max_resolution;
+ if (profile >= media::H264PROFILE_BASELINE &&
+ profile <= media::H264PROFILE_HIGH) {
+ max_resolution = GetMaxH264Resolution();
+ } else {
+ // TODO(ananta)
+ // Detect this properly for VP8/VP9 profiles.
+ max_resolution = std::make_pair(4096, 2160);
+ }
+ return max_resolution;
+}
+
+std::pair<int, int> DXVAVideoDecodeAccelerator::GetMaxH264Resolution() {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::GetMaxH264Resolution");
+ // The H.264 resolution detection operation is expensive. This static flag
+ // allows us to run the detection once.
+ static bool resolution_detected = false;
+ // Use 1088 to account for 16x16 macroblocks.
+ static std::pair<int, int> max_resolution = std::make_pair(1920, 1088);
+ if (resolution_detected)
+ return max_resolution;
+
+ resolution_detected = true;
+
+ // On Windows 7 the maximum resolution supported by media foundation is
+ // 1920 x 1088.
+ if (base::win::GetVersion() == base::win::VERSION_WIN7)
+ return max_resolution;
+
+ // To detect if a driver supports the desired resolutions, we try and create
+ // a DXVA decoder instance for that resolution and profile. If that succeeds
+ // we assume that the driver supports H/W H.264 decoding for that resolution.
+ HRESULT hr = E_FAIL;
+ base::win::ScopedComPtr<ID3D11Device> device;
+
+ {
+ TRACE_EVENT0("gpu,startup",
+ "GetMaxH264Resolution. QueryDeviceObjectFromANGLE");
+
+ device = QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
+ if (!device.get())
+ return max_resolution;
+ }
+
+ base::win::ScopedComPtr<ID3D11VideoDevice> video_device;
+ hr = device.QueryInterface(IID_ID3D11VideoDevice,
+ video_device.ReceiveVoid());
+ if (FAILED(hr))
+ return max_resolution;
+
+ GUID decoder_guid = {};
+
+ {
+ TRACE_EVENT0("gpu,startup",
+ "GetMaxH264Resolution. H.264 guid search begin");
+ // Enumerate supported video profiles and look for the H264 profile.
+ bool found = false;
+ UINT profile_count = video_device->GetVideoDecoderProfileCount();
+ for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) {
+ GUID profile_id = {};
+ hr = video_device->GetVideoDecoderProfile(profile_idx, &profile_id);
+ if (SUCCEEDED(hr) &&
+ (profile_id == DXVA2_ModeH264_E ||
+ profile_id == DXVA2_Intel_ModeH264_E)) {
+ decoder_guid = profile_id;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return max_resolution;
+ }
+
+ // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
+ // creating surfaces larger than 1920 x 1088.
+ if (IsLegacyGPU(device.get()))
+ return max_resolution;
+
+ // We look for the following resolutions in the driver.
+ // TODO(ananta)
+ // Look into whether this list needs to be expanded.
+ static std::pair<int, int> resolution_array[] = {
+ // Use 1088 to account for 16x16 macroblocks.
+ std::make_pair(1920, 1088),
+ std::make_pair(2560, 1440),
+ std::make_pair(3840, 2160),
+ std::make_pair(4096, 2160),
+ std::make_pair(4096, 2304),
+ };
+
+ {
+ TRACE_EVENT0("gpu,startup",
+ "GetMaxH264Resolution. Resolution search begin");
+
+ for (size_t res_idx = 0; res_idx < arraysize(resolution_array);
+ res_idx++) {
+ D3D11_VIDEO_DECODER_DESC desc = {};
+ desc.Guid = decoder_guid;
+ desc.SampleWidth = resolution_array[res_idx].first;
+ desc.SampleHeight = resolution_array[res_idx].second;
+ desc.OutputFormat = DXGI_FORMAT_NV12;
+ UINT config_count = 0;
+ hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count);
+ if (FAILED(hr) || config_count == 0)
+ return max_resolution;
+
+ D3D11_VIDEO_DECODER_CONFIG config = {};
+ hr = video_device->GetVideoDecoderConfig(&desc, 0, &config);
+ if (FAILED(hr))
+ return max_resolution;
+
+ base::win::ScopedComPtr<ID3D11VideoDecoder> video_decoder;
+ hr = video_device->CreateVideoDecoder(&desc, &config,
+ video_decoder.Receive());
+ if (!video_decoder.get())
+ return max_resolution;
+
+ max_resolution = resolution_array[res_idx];
+ }
+ }
+ return max_resolution;
+}
+
+// static
+bool DXVAVideoDecodeAccelerator::IsLegacyGPU(ID3D11Device* device) {
+ static const int kAMDGPUId1 = 0x1002;
+ static const int kAMDGPUId2 = 0x1022;
+ static const int kIntelGPU = 0x8086;
+
+ static bool legacy_gpu = true;
+ // This flag ensures that we determine the GPU type once.
+ static bool legacy_gpu_determined = false;
+
+ if (legacy_gpu_determined)
+ return legacy_gpu;
+
+ legacy_gpu_determined = true;
+
+ base::win::ScopedComPtr<IDXGIDevice> dxgi_device;
+ HRESULT hr = dxgi_device.QueryFrom(device);
+ if (FAILED(hr))
+ return legacy_gpu;
+
+ base::win::ScopedComPtr<IDXGIAdapter> adapter;
+ hr = dxgi_device->GetAdapter(adapter.Receive());
+ if (FAILED(hr))
+ return legacy_gpu;
+
+ DXGI_ADAPTER_DESC adapter_desc = {};
+ hr = adapter->GetDesc(&adapter_desc);
+ if (FAILED(hr))
+ return legacy_gpu;
+
+ // We check if the device is an Intel or an AMD device and whether it is in
+ // the global list defined by the g_AMDUVD3GPUList and g_IntelLegacyGPUList
+ // arrays above. If yes then the device is treated as a legacy device.
+ if ((adapter_desc.VendorId == kAMDGPUId1) ||
+ adapter_desc.VendorId == kAMDGPUId2) {
+ {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::IsLegacyGPU. AMD check");
+ for (size_t i = 0; i < arraysize(g_AMDUVD3GPUList); i++) {
+ if (adapter_desc.DeviceId == g_AMDUVD3GPUList[i])
+ return legacy_gpu;
+ }
+ }
+ } else if (adapter_desc.VendorId == kIntelGPU) {
+ {
+ TRACE_EVENT0("gpu,startup",
+ "DXVAVideoDecodeAccelerator::IsLegacyGPU. Intel check");
+ for (size_t i = 0; i < arraysize(g_IntelLegacyGPUList); i++) {
+ if (adapter_desc.DeviceId == g_IntelLegacyGPUList[i])
+ return legacy_gpu;
+ }
+ }
+ }
+ legacy_gpu = false;
+ return legacy_gpu;
+}
+
bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
HMODULE decoder_dll = NULL;
@@ -1104,24 +1683,26 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
"msmpeg2vdec.dll required for decoding is not loaded",
false);
- // Check version of DLL, version 6.7.7140 is blacklisted due to high crash
+ // Check version of DLL, version 6.1.7140 is blacklisted due to high crash
// rates in browsers loading that DLL. If that is the version installed we
// fall back to software decoding. See crbug/403440.
- FileVersionInfo* version_info =
- FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll);
+ scoped_ptr<FileVersionInfo> version_info(
+ FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll));
RETURN_ON_FAILURE(version_info,
"unable to get version of msmpeg2vdec.dll",
false);
base::string16 file_version = version_info->file_version();
RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos,
- "blacklisted version of msmpeg2vdec.dll 6.7.7140",
+ "blacklisted version of msmpeg2vdec.dll 6.1.7140",
false);
codec_ = media::kCodecH264;
clsid = __uuidof(CMSH264DecoderMFT);
- } else if ((profile == media::VP8PROFILE_ANY ||
- profile == media::VP9PROFILE_ANY) &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableAcceleratedVpxDecode)) {
+ } else if (enable_accelerated_vpx_decode_ &&
+ (profile == media::VP8PROFILE_ANY ||
+ profile == media::VP9PROFILE_PROFILE0 ||
+ profile == media::VP9PROFILE_PROFILE1 ||
+ profile == media::VP9PROFILE_PROFILE2 ||
+ profile == media::VP9PROFILE_PROFILE3)) {
int program_files_key = base::DIR_PROGRAM_FILES;
if (base::win::OSInfo::GetInstance()->wow64_status() ==
base::win::OSInfo::WOW64_ENABLED) {
@@ -1230,19 +1811,24 @@ bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() {
DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr;
}
+ auto gl_context = get_gl_context_cb_.Run();
+ RETURN_ON_FAILURE(gl_context, "Couldn't get GL context", false);
+
// The decoder should use DX11 iff
// 1. The underlying H/W decoder supports it.
// 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for
// this. This should always be true for Windows 8+.
// 3. ANGLE is using DX11.
- DCHECK(gl_context_);
if (create_dxgi_device_manager_ &&
- (gl_context_->GetGLRenderer().find("Direct3D11") !=
- std::string::npos)) {
+ (gl_context->GetGLRenderer().find("Direct3D11") != std::string::npos)) {
UINT32 dx11_aware = 0;
attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware);
use_dx11_ = !!dx11_aware;
}
+
+ use_keyed_mutex_ =
+ use_dx11_ && gfx::GLSurfaceEGL::HasEGLExtension("EGL_ANGLE_keyed_mutex");
+
return true;
}
@@ -1436,8 +2022,9 @@ void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
if (!output_picture_buffers_.size())
return;
- RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(),
- "Failed to make context current", PLATFORM_FAILURE,);
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
OutputBuffers::iterator index;
@@ -1449,7 +2036,6 @@ void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
PendingSampleInfo* pending_sample = NULL;
{
base::AutoLock lock(decoder_lock_);
-
PendingSampleInfo& sample_info = pending_output_samples_.front();
if (sample_info.picture_buffer_id != -1)
continue;
@@ -1533,13 +2119,22 @@ void DXVAVideoDecodeAccelerator::Invalidate() {
if (GetState() == kUninitialized)
return;
+ // Best effort to make the GL context current.
+ make_context_current_cb_.Run();
+
decoder_thread_.Stop();
weak_this_factory_.InvalidateWeakPtrs();
output_picture_buffers_.clear();
stale_output_picture_buffers_.clear();
pending_output_samples_.clear();
- pending_input_buffers_.clear();
+ // We want to continue processing pending input after detecting a config
+ // change.
+ if (GetState() != kConfigChange)
+ pending_input_buffers_.clear();
decoder_.Release();
+ pictures_requested_ = false;
+
+ config_change_detector_.reset();
if (use_dx11_) {
if (video_format_converter_mft_.get()) {
@@ -1552,6 +2147,7 @@ void DXVAVideoDecodeAccelerator::Invalidate() {
d3d11_device_manager_.Release();
d3d11_query_.Release();
dx11_video_format_converter_media_type_needs_init_ = true;
+ multi_threaded_.Release();
} else {
d3d9_.Release();
d3d9_device_ex_.Release();
@@ -1591,10 +2187,8 @@ void DXVAVideoDecodeAccelerator::RequestPictureBuffers(int width, int height) {
DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
// This task could execute after the decoder has been torn down.
if (GetState() != kUninitialized && client_) {
- client_->ProvidePictureBuffers(
- kNumPictureBuffers,
- gfx::Size(width, height),
- GL_TEXTURE_2D);
+ client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
+ gfx::Size(width, height), GL_TEXTURE_2D);
}
}
@@ -1706,13 +2300,31 @@ void DXVAVideoDecodeAccelerator::DecodeInternal(
return;
}
+ // Check if the resolution, bit rate, etc changed in the stream. If yes we
+ // reinitialize the decoder to ensure that the stream decodes correctly.
+ bool config_changed = false;
+
+ HRESULT hr = CheckConfigChanged(sample.get(), &config_changed);
+ RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to check video stream config",
+ PLATFORM_FAILURE,);
+
+ if (config_changed) {
+ pending_input_buffers_.push_back(sample);
+ main_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DXVAVideoDecodeAccelerator::ConfigChanged,
+ weak_this_factory_.GetWeakPtr(),
+ config_));
+ return;
+ }
+
if (!inputs_before_decode_) {
TRACE_EVENT_ASYNC_BEGIN0("gpu", "DXVAVideoDecodeAccelerator.Decoding",
this);
}
inputs_before_decode_++;
- HRESULT hr = decoder_->ProcessInput(0, sample.get(), 0);
+ hr = decoder_->ProcessInput(0, sample.get(), 0);
// As per msdn if the decoder returns MF_E_NOTACCEPTING then it means that it
// has enough data to produce one or more output samples. In this case the
// recommended options are to
@@ -1790,7 +2402,7 @@ void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
main_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
- weak_this_factory_.GetWeakPtr()));
+ weak_this_factory_.GetWeakPtr(), false));
main_thread_task_runner_->PostTask(
FROM_HERE,
@@ -1800,13 +2412,17 @@ void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
height));
}
-void DXVAVideoDecodeAccelerator::DismissStaleBuffers() {
+void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+
OutputBuffers::iterator index;
for (index = output_picture_buffers_.begin();
index != output_picture_buffers_.end();
++index) {
- if (index->second->available()) {
+ if (force || index->second->available()) {
DVLOG(1) << "Dismissing picture id: " << index->second->id();
client_->DismissPictureBuffer(index->second->id());
} else {
@@ -1821,6 +2437,10 @@ void DXVAVideoDecodeAccelerator::DismissStaleBuffers() {
void DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer(
int32_t picture_buffer_id) {
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
+
OutputBuffers::iterator it = stale_output_picture_buffers_.find(
picture_buffer_id);
DCHECK(it != stale_output_picture_buffers_.end());
@@ -1935,13 +2555,15 @@ void DXVAVideoDecodeAccelerator::CopySurfaceComplete(
if (picture_buffer->available())
return;
- RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(),
- "Failed to make context current", PLATFORM_FAILURE,);
+ RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
+ "Failed to make context current",
+ PLATFORM_FAILURE, );
DCHECK(!output_picture_buffers_.empty());
- picture_buffer->CopySurfaceComplete(src_surface,
- dest_surface);
+ bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface);
+ RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
+ PLATFORM_FAILURE, );
NotifyPictureReady(picture_buffer->id(), input_buffer_id);
@@ -1964,11 +2586,14 @@ void DXVAVideoDecodeAccelerator::CopySurfaceComplete(
base::Unretained(this)));
}
-void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture,
- ID3D11Texture2D* dest_texture,
- IMFSample* video_frame,
- int picture_buffer_id,
- int input_buffer_id) {
+void DXVAVideoDecodeAccelerator::CopyTexture(
+ ID3D11Texture2D* src_texture,
+ ID3D11Texture2D* dest_texture,
+ base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
+ uint64_t keyed_mutex_value,
+ IMFSample* video_frame,
+ int picture_buffer_id,
+ int input_buffer_id) {
HRESULT hr = E_FAIL;
DCHECK(use_dx11_);
@@ -2005,14 +2630,11 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture,
}
decoder_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&DXVAVideoDecodeAccelerator::CopyTexture,
- base::Unretained(this),
- src_texture,
- dest_texture,
- input_sample_for_conversion.Detach(),
- picture_buffer_id,
- input_buffer_id));
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopyTexture,
+ base::Unretained(this), src_texture, dest_texture,
+ dest_keyed_mutex, keyed_mutex_value,
+ input_sample_for_conversion.Detach(),
+ picture_buffer_id, input_buffer_id));
return;
}
@@ -2023,6 +2645,13 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture,
DCHECK(video_format_converter_mft_.get());
+ if (dest_keyed_mutex) {
+ HRESULT hr =
+ dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs);
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.",
+ PLATFORM_FAILURE, );
+ }
// The video processor MFT requires output samples to be allocated by the
// caller. We create a sample with a buffer backed with the ID3D11Texture2D
// interface exposed by ANGLE. This works nicely as this ensures that the
@@ -2077,18 +2706,27 @@ void DXVAVideoDecodeAccelerator::CopyTexture(ID3D11Texture2D* src_texture,
"Failed to convert output sample format.", PLATFORM_FAILURE,);
}
- d3d11_device_context_->Flush();
- d3d11_device_context_->End(d3d11_query_.get());
+ if (dest_keyed_mutex) {
+ HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1);
+ RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.",
+ PLATFORM_FAILURE, );
- decoder_thread_task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
- base::Unretained(this), 0,
- reinterpret_cast<IDirect3DSurface9*>(NULL),
- reinterpret_cast<IDirect3DSurface9*>(NULL),
- picture_buffer_id, input_buffer_id),
- base::TimeDelta::FromMilliseconds(
- kFlushDecoderSurfaceTimeoutMs));
+ main_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
+ weak_this_factory_.GetWeakPtr(), nullptr, nullptr,
+ picture_buffer_id, input_buffer_id));
+ } else {
+ d3d11_device_context_->Flush();
+ d3d11_device_context_->End(d3d11_query_.get());
+
+ decoder_thread_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder,
+ base::Unretained(this), 0,
+ reinterpret_cast<IDirect3DSurface9*>(NULL),
+ reinterpret_cast<IDirect3DSurface9*>(NULL),
+ picture_buffer_id, input_buffer_id),
+ base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
+ }
}
void DXVAVideoDecodeAccelerator::FlushDecoder(
@@ -2290,12 +2928,6 @@ bool DXVAVideoDecodeAccelerator::SetTransformOutputType(
RETURN_ON_HR_FAILURE(hr, "Failed to set media type attributes", false);
}
hr = transform->SetOutputType(0, media_type.get(), 0); // No flags
- if (FAILED(hr)) {
- base::debug::Alias(&hr);
- // TODO(ananta)
- // Remove this CHECK when this stabilizes in the field.
- CHECK(false);
- }
RETURN_ON_HR_FAILURE(hr, "Failed to set output type", false);
return true;
}
@@ -2304,4 +2936,39 @@ bool DXVAVideoDecodeAccelerator::SetTransformOutputType(
return false;
}
+HRESULT DXVAVideoDecodeAccelerator::CheckConfigChanged(
+ IMFSample* sample, bool* config_changed) {
+ if (codec_ != media::kCodecH264)
+ return S_FALSE;
+
+ base::win::ScopedComPtr<IMFMediaBuffer> buffer;
+ HRESULT hr = sample->GetBufferByIndex(0, buffer.Receive());
+ RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr);
+
+ MediaBufferScopedPointer scoped_media_buffer(buffer.get());
+
+ if (!config_change_detector_->DetectConfig(
+ scoped_media_buffer.get(),
+ scoped_media_buffer.current_length())) {
+ RETURN_ON_HR_FAILURE(E_FAIL, "Failed to detect H.264 stream config",
+ E_FAIL);
+ }
+ *config_changed = config_change_detector_->config_changed();
+ return S_OK;
+}
+
+void DXVAVideoDecodeAccelerator::ConfigChanged(
+ const Config& config) {
+ DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
+
+ SetState(kConfigChange);
+ DismissStaleBuffers(true);
+ Invalidate();
+ Initialize(config_, client_);
+ decoder_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
+ base::Unretained(this)));
+}
+
} // namespace content
diff --git a/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.h b/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.h
index d3aeda62c9b..01c15e62430 100644
--- a/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.h
+++ b/chromium/content/common/gpu/media/dxva_video_decode_accelerator_win.h
@@ -7,6 +7,7 @@
#include <d3d11.h>
#include <d3d9.h>
+#include <initguid.h>
#include <stdint.h>
// Work around bug in this header by disabling the relevant warning for it.
// https://connect.microsoft.com/VisualStudio/feedback/details/911260/dxva2api-h-in-win8-sdk-triggers-c4201-with-w4
@@ -29,6 +30,8 @@
#include "base/threading/thread.h"
#include "base/win/scoped_comptr.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
+#include "media/filters/h264_parser.h"
#include "media/video/video_decode_accelerator.h"
interface IMFSample;
@@ -44,6 +47,43 @@ typedef HRESULT (WINAPI* CreateDXGIDeviceManager)(
namespace content {
+// Provides functionality to detect H.264 stream configuration changes.
+// TODO(ananta)
+// Move this to a common place so that all VDA's can use this.
+class H264ConfigChangeDetector {
+ public:
+ H264ConfigChangeDetector();
+ ~H264ConfigChangeDetector();
+
+ // Detects stream configuration changes.
+ // Returns false on failure.
+ bool DetectConfig(const uint8_t* stream, unsigned int size);
+
+ bool config_changed() const {
+ return config_changed_;
+ }
+
+ private:
+ // These fields are used to track the SPS/PPS in the H.264 bitstream and
+ // are eventually compared against the SPS/PPS in the bitstream to detect
+ // a change.
+ int last_sps_id_;
+ std::vector<uint8_t> last_sps_;
+ int last_pps_id_;
+ std::vector<uint8_t> last_pps_;
+ // Set to true if we detect a stream configuration change.
+ bool config_changed_;
+ // We want to indicate configuration changes only after we see IDR slices.
+ // This flag tracks that we potentially have a configuration change which
+ // we want to honor after we see an IDR slice.
+ bool pending_config_changed_;
+
+ scoped_ptr<media::H264Parser> parser_;
+
+ DISALLOW_COPY_AND_ASSIGN(H264ConfigChangeDetector);
+};
+
+
// Class to provide a DXVA 2.0 based accelerator using the Microsoft Media
// foundation APIs via the VideoDecodeAccelerator interface.
// This class lives on a single thread and DCHECKs that it is never accessed
@@ -57,12 +97,14 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
kResetting, // upon received Reset(), before ResetDone()
kStopped, // upon output EOS received.
kFlushing, // upon flush request received.
+ kConfigChange, // stream configuration change detected.
};
// Does not take ownership of |client| which must outlive |*this|.
- explicit DXVAVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- gfx::GLContext* gl_context);
+ DXVAVideoDecodeAccelerator(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ bool enable_accelerated_vpx_decode);
~DXVAVideoDecodeAccelerator() override;
// media::VideoDecodeAccelerator implementation.
@@ -74,7 +116,10 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
GLenum GetSurfaceInternalFormat() const override;
static media::VideoDecodeAccelerator::SupportedProfiles
@@ -87,6 +132,23 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
typedef void* EGLConfig;
typedef void* EGLSurface;
+ // Returns the minimum resolution for the |profile| passed in.
+ static std::pair<int, int> GetMinResolution(
+ const media::VideoCodecProfile profile);
+
+ // Returns the maximum resolution for the |profile| passed in.
+ static std::pair<int, int> GetMaxResolution(
+ const media::VideoCodecProfile profile);
+
+ // Returns the maximum resolution for H264 video.
+ static std::pair<int, int> GetMaxH264Resolution();
+
+ // Certain AMD GPU drivers like R600, R700, Evergreen and Cayman and
+ // some second generation Intel GPU drivers crash if we create a video
+ // device with a resolution higher then 1920 x 1088. This function
+ // checks if the GPU is in this list and if yes returns true.
+ static bool IsLegacyGPU(ID3D11Device* device);
+
// Creates and initializes an instance of the D3D device and the
// corresponding device manager. The device manager instance is eventually
// passed to the IMFTransform interface implemented by the decoder.
@@ -178,7 +240,7 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
typedef std::map<int32_t, linked_ptr<DXVAPictureBuffer>> OutputBuffers;
// Tells the client to dismiss the stale picture buffers passed in.
- void DismissStaleBuffers();
+ void DismissStaleBuffers(bool force);
// Called after the client indicates we can recycle a stale picture buffer.
void DeferredDismissStaleBuffer(int32_t picture_buffer_id);
@@ -191,10 +253,6 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
// the decoder thread. Thread safe.
State GetState();
- // Worker function for the Decoder Reset functionality. Executes on the
- // decoder thread and queues tasks on the main thread as needed.
- void ResetHelper();
-
// Starts the thread used for decoding.
void StartDecoderThread();
@@ -222,6 +280,8 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
// is the sample containing the frame to be copied.
void CopyTexture(ID3D11Texture2D* src_texture,
ID3D11Texture2D* dest_texture,
+ base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
+ uint64_t keyed_mutex_value,
IMFSample* video_frame,
int picture_buffer_id,
int input_buffer_id);
@@ -235,6 +295,10 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
int picture_buffer_id,
int input_buffer_id);
+ // Polls to wait for GPU commands to be finished on the picture buffer
+ // before reusing it.
+ void WaitForOutputBuffer(int32_t picture_buffer_id, int count);
+
// Initializes the DX11 Video format converter media types.
// Returns true on success.
bool InitializeDX11VideoFormatConverterMediaType(int width, int height);
@@ -257,6 +321,18 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
int width,
int height);
+ // Checks if the resolution, bitrate etc of the stream changed. We do this
+ // by keeping track of the SPS/PPS frames and if they change we assume
+ // that the configuration changed.
+ // Returns S_OK or S_FALSE on succcess.
+ // The |config_changed| parameter is set to true if we detect a change in the
+ // stream.
+ HRESULT CheckConfigChanged(IMFSample* sample, bool* config_changed);
+
+ // Called when we detect a stream configuration change. We reinitialize the
+ // decoder here.
+ void ConfigChanged(const Config& config);
+
// To expose client callbacks from VideoDecodeAccelerator.
media::VideoDecodeAccelerator::Client* client_;
@@ -340,8 +416,10 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
typedef std::list<base::win::ScopedComPtr<IMFSample>> PendingInputs;
PendingInputs pending_input_buffers_;
+ // Callback to get current GLContext.
+ GetGLContextCallback get_gl_context_cb_;
// Callback to set the correct gl context.
- base::Callback<bool(void)> make_context_current_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
// Which codec we are decoding with hardware acceleration.
media::VideoCodec codec_;
@@ -373,16 +451,30 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
// H/W decoding.
bool use_dx11_;
+ // True if we should use DXGI keyed mutexes to synchronize between the two
+ // contexts.
+ bool use_keyed_mutex_;
+
// Set to true if the DX11 video format converter input media types need to
// be initialized. Defaults to true.
bool dx11_video_format_converter_media_type_needs_init_;
- // The GLContext to be used by the decoder.
- scoped_refptr<gfx::GLContext> gl_context_;
-
// Set to true if we are sharing ANGLE's device.
bool using_angle_device_;
+ // Enables experimental hardware acceleration for VP8/VP9 video decoding.
+ const bool enable_accelerated_vpx_decode_;
+
+ // The media foundation H.264 decoder has problems handling changes like
+ // resolution change, bitrate change etc. If we reinitialize the decoder
+ // when these changes occur then, the decoder works fine. The
+ // H264ConfigChangeDetector class provides functionality to check if the
+ // stream configuration changed.
+ scoped_ptr<H264ConfigChangeDetector> config_change_detector_;
+
+ // Contains the initialization parameters for the video.
+ Config config_;
+
// WeakPtrFactory for posting tasks back to |this|.
base::WeakPtrFactory<DXVAVideoDecodeAccelerator> weak_this_factory_;
diff --git a/chromium/content/common/gpu/media/fake_video_decode_accelerator.cc b/chromium/content/common/gpu/media/fake_video_decode_accelerator.cc
index 7524dd18ebf..01ac07dcd3b 100644
--- a/chromium/content/common/gpu/media/fake_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/fake_video_decode_accelerator.cc
@@ -29,17 +29,14 @@ static const unsigned int kNumBuffers = media::limits::kMaxVideoFrames +
(media::limits::kMaxVideoFrames & 1u);
FakeVideoDecodeAccelerator::FakeVideoDecodeAccelerator(
- gfx::GLContext* gl,
- gfx::Size size,
- const base::Callback<bool(void)>& make_context_current)
+ const gfx::Size& size,
+ const MakeGLContextCurrentCallback& make_context_current_cb)
: child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
client_(NULL),
- make_context_current_(make_context_current),
- gl_(gl),
+ make_context_current_cb_(make_context_current_cb),
frame_buffer_size_(size),
flushing_(false),
- weak_this_factory_(this) {
-}
+ weak_this_factory_(this) {}
FakeVideoDecodeAccelerator::~FakeVideoDecodeAccelerator() {
}
@@ -59,14 +56,23 @@ bool FakeVideoDecodeAccelerator::Initialize(const Config& config,
// V4L2VideoDecodeAccelerator waits until first decode call to ask for buffers
// This class asks for it on initialization instead.
client_ = client;
- client_->ProvidePictureBuffers(kNumBuffers,
- frame_buffer_size_,
+ client_->ProvidePictureBuffers(kNumBuffers, 1, frame_buffer_size_,
kDefaultTextureTarget);
return true;
}
void FakeVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
+ // We won't really read from the bitstream_buffer, close the handle.
+ if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
+ base::SharedMemory::CloseHandle(bitstream_buffer.handle());
+
+ if (bitstream_buffer.id() < 0) {
+ LOG(ERROR) << "Invalid bitstream: id=" << bitstream_buffer.id();
+ client_->NotifyError(INVALID_ARGUMENT);
+ return;
+ }
+
int bitstream_buffer_id = bitstream_buffer.id();
queued_bitstream_ids_.push(bitstream_buffer_id);
child_task_runner_->PostTask(
@@ -93,12 +99,13 @@ void FakeVideoDecodeAccelerator::AssignPictureBuffers(
memset(black_data.get(),
0,
frame_buffer_size_.width() * frame_buffer_size_.height() * 4);
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
return;
}
for (size_t index = 0; index < buffers.size(); ++index) {
- glBindTexture(GL_TEXTURE_2D, buffers[index].texture_id());
+ DCHECK_LE(1u, buffers[index].texture_ids().size());
+ glBindTexture(GL_TEXTURE_2D, buffers[index].texture_ids()[0]);
// Every other frame white and the rest black.
uint8_t* data = index % 2 ? white_data.get() : black_data.get();
glTexImage2D(GL_TEXTURE_2D,
@@ -152,8 +159,10 @@ void FakeVideoDecodeAccelerator::Destroy() {
delete this;
}
-bool FakeVideoDecodeAccelerator::CanDecodeOnIOThread() {
- return true;
+bool FakeVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
+ return false;
}
void FakeVideoDecodeAccelerator::DoPictureReady() {
diff --git a/chromium/content/common/gpu/media/fake_video_decode_accelerator.h b/chromium/content/common/gpu/media/fake_video_decode_accelerator.h
index 7dcbfda2e77..10d47822b45 100644
--- a/chromium/content/common/gpu/media/fake_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/fake_video_decode_accelerator.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "media/video/video_decode_accelerator.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gl/gl_context.h"
@@ -23,9 +24,8 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator
: public media::VideoDecodeAccelerator {
public:
FakeVideoDecodeAccelerator(
- gfx::GLContext* gl,
- gfx::Size size,
- const base::Callback<bool(void)>& make_context_current);
+ const gfx::Size& size,
+ const MakeGLContextCurrentCallback& make_context_current_cb);
~FakeVideoDecodeAccelerator() override;
bool Initialize(const Config& config, Client* client) override;
@@ -36,7 +36,10 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
private:
void DoPictureReady();
@@ -49,8 +52,7 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator
Client* client_;
// Make our context current before running any GL entry points.
- base::Callback<bool(void)> make_context_current_;
- gfx::GLContext* gl_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
// Output picture size.
gfx::Size frame_buffer_size_;
diff --git a/chromium/content/common/gpu/media/gpu_arc_video_service.cc b/chromium/content/common/gpu/media/gpu_arc_video_service.cc
deleted file mode 100644
index 91d36980ad1..00000000000
--- a/chromium/content/common/gpu/media/gpu_arc_video_service.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 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 "content/common/gpu/media/gpu_arc_video_service.h"
-
-#include "base/logging.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_sync_channel.h"
-
-namespace content {
-
-// TODO(kcwu) implement ArcVideoAccelerator::Client.
-class GpuArcVideoService::AcceleratorStub : public IPC::Listener,
- public IPC::Sender {
- public:
- // |owner| outlives AcceleratorStub.
- explicit AcceleratorStub(GpuArcVideoService* owner) : owner_(owner) {}
-
- ~AcceleratorStub() override {
- DCHECK(thread_checker_.CalledOnValidThread());
- channel_->Close();
- }
-
- IPC::ChannelHandle CreateChannel(
- base::WaitableEvent* shutdown_event,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) {
- IPC::ChannelHandle handle =
- IPC::Channel::GenerateVerifiedChannelID("arc-video");
- channel_ = IPC::SyncChannel::Create(handle, IPC::Channel::MODE_SERVER, this,
- io_task_runner, false, shutdown_event);
- base::ScopedFD client_fd = channel_->TakeClientFileDescriptor();
- DCHECK(client_fd.is_valid());
- handle.socket = base::FileDescriptor(std::move(client_fd));
- return handle;
- }
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* msg) override {
- DCHECK(msg);
- return channel_->Send(msg);
- }
-
- // IPC::Listener implementation:
- void OnChannelError() override {
- DCHECK(thread_checker_.CalledOnValidThread());
- // RemoveClient will delete |this|.
- owner_->RemoveClient(this);
- }
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& msg) override {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // TODO(kcwu) Add handlers here.
- return false;
- }
-
- private:
- base::ThreadChecker thread_checker_;
- GpuArcVideoService* const owner_;
- scoped_ptr<IPC::SyncChannel> channel_;
-};
-
-GpuArcVideoService::GpuArcVideoService(
- base::WaitableEvent* shutdown_event,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
- : shutdown_event_(shutdown_event), io_task_runner_(io_task_runner) {}
-
-GpuArcVideoService::~GpuArcVideoService() {}
-
-void GpuArcVideoService::CreateChannel(const CreateChannelCallback& callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- scoped_ptr<AcceleratorStub> stub(new AcceleratorStub(this));
-
- IPC::ChannelHandle handle =
- stub->CreateChannel(shutdown_event_, io_task_runner_);
- accelerator_stubs_[stub.get()] = std::move(stub);
-
- callback.Run(handle);
-}
-
-void GpuArcVideoService::RemoveClient(AcceleratorStub* stub) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- accelerator_stubs_.erase(stub);
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/media/gpu_arc_video_service.h b/chromium/content/common/gpu/media/gpu_arc_video_service.h
deleted file mode 100644
index 131150c9f94..00000000000
--- a/chromium/content/common/gpu/media/gpu_arc_video_service.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_GPU_ARC_VIDEO_SERVICE_H_
-#define CONTENT_COMMON_GPU_MEDIA_GPU_ARC_VIDEO_SERVICE_H_
-
-#include <map>
-
-#include "base/callback.h"
-#include "base/threading/thread_checker.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-class WaitableEvent;
-}
-
-namespace IPC {
-struct ChannelHandle;
-}
-
-namespace content {
-
-// GpuArcVideoService manages life-cycle and IPC message translation for
-// ArcVideoAccelerator.
-//
-// For each creation request from GpuChannelManager, GpuArcVideoService will
-// create a new IPC channel.
-class GpuArcVideoService {
- public:
- class AcceleratorStub;
- using CreateChannelCallback = base::Callback<void(const IPC::ChannelHandle&)>;
-
- // |shutdown_event| should signal an event when this process is about to be
- // shut down in order to notify our new IPC channel to terminate.
- GpuArcVideoService(
- base::WaitableEvent* shutdown_event,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
-
- // Upon deletion, all ArcVideoAccelerator will be deleted and the associated
- // IPC channels are closed.
- ~GpuArcVideoService();
-
- // Creates a new accelerator stub. The creation result will be sent back via
- // |callback|.
- void CreateChannel(const CreateChannelCallback& callback);
-
- // Removes the reference of |stub| (and trigger deletion) from this class.
- void RemoveClient(AcceleratorStub* stub);
-
- private:
- base::ThreadChecker thread_checker_;
-
- // Shutdown event of GPU process.
- base::WaitableEvent* shutdown_event_;
-
- // GPU io thread task runner.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- // Bookkeeping all accelerator stubs.
- std::map<AcceleratorStub*, scoped_ptr<AcceleratorStub>> accelerator_stubs_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuArcVideoService);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_MEDIA_GPU_ARC_VIDEO_SERVICE_H_
diff --git a/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc b/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc
index 7408e46d927..3e256073e84 100644
--- a/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.cc
@@ -13,13 +13,14 @@
#include "base/memory/shared_memory.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_messages.h"
+#include "gpu/ipc/service/gpu_channel.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/message_filter.h"
#include "media/filters/jpeg_parser.h"
+#include "media/gpu/ipc/common/media_messages.h"
#include "ui/gfx/geometry/size.h"
#if defined(OS_CHROMEOS)
@@ -41,12 +42,6 @@ void DecodeFinished(scoped_ptr<base::SharedMemory> shm) {
}
bool VerifyDecodeParams(const AcceleratedJpegDecoderMsg_Decode_Params& params) {
- if (params.input_buffer_id < 0) {
- LOG(ERROR) << "BitstreamBuffer id " << params.input_buffer_id
- << " out of range";
- return false;
- }
-
const int kJpegMaxDimension = UINT16_MAX;
if (params.coded_size.IsEmpty() ||
params.coded_size.width() > kJpegMaxDimension ||
@@ -55,11 +50,6 @@ bool VerifyDecodeParams(const AcceleratedJpegDecoderMsg_Decode_Params& params) {
return false;
}
- if (!base::SharedMemory::IsHandleValid(params.input_buffer_handle)) {
- LOG(ERROR) << "invalid input_buffer_handle";
- return false;
- }
-
if (!base::SharedMemory::IsHandleValid(params.output_video_frame_handle)) {
LOG(ERROR) << "invalid output_video_frame_handle";
return false;
@@ -163,13 +153,12 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
void AddClientOnIOThread(int32_t route_id,
Client* client,
- IPC::Message* reply_msg) {
+ base::Callback<void(bool)> response) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DCHECK(client_map_.count(route_id) == 0);
client_map_[route_id] = client;
- GpuMsg_CreateJpegDecoder::WriteReplyParams(reply_msg, true);
- SendOnIOThread(reply_msg);
+ response.Run(true);
}
void OnDestroyOnIOThread(const int32_t* route_id) {
@@ -208,34 +197,28 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
if (!VerifyDecodeParams(params)) {
NotifyDecodeStatusOnIOThread(
- *route_id, params.input_buffer_id,
+ *route_id, params.input_buffer.id(),
media::JpegDecodeAccelerator::INVALID_ARGUMENT);
- if (base::SharedMemory::IsHandleValid(params.input_buffer_handle))
- base::SharedMemory::CloseHandle(params.input_buffer_handle);
if (base::SharedMemory::IsHandleValid(params.output_video_frame_handle))
base::SharedMemory::CloseHandle(params.output_video_frame_handle);
return;
}
// For handles in |params|, from now on, |params.output_video_frame_handle|
- // is taken cared by scoper. |params.input_buffer_handle| need to be closed
- // manually for early exits.
+ // is taken cared by scoper. |params.input_buffer.handle()| need to be
+ // closed manually for early exits.
scoped_ptr<base::SharedMemory> output_shm(
new base::SharedMemory(params.output_video_frame_handle, false));
if (!output_shm->Map(params.output_buffer_size)) {
LOG(ERROR) << "Could not map output shared memory for input buffer id "
- << params.input_buffer_id;
+ << params.input_buffer.id();
NotifyDecodeStatusOnIOThread(
- *route_id, params.input_buffer_id,
+ *route_id, params.input_buffer.id(),
media::JpegDecodeAccelerator::PLATFORM_FAILURE);
- base::SharedMemory::CloseHandle(params.input_buffer_handle);
+ base::SharedMemory::CloseHandle(params.input_buffer.handle());
return;
}
- media::BitstreamBuffer input_buffer(params.input_buffer_id,
- params.input_buffer_handle,
- params.input_buffer_size);
-
uint8_t* shm_memory = static_cast<uint8_t*>(output_shm->memory());
scoped_refptr<media::VideoFrame> frame =
media::VideoFrame::WrapExternalSharedMemory(
@@ -250,11 +233,11 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
base::TimeDelta()); // timestamp
if (!frame.get()) {
LOG(ERROR) << "Could not create VideoFrame for input buffer id "
- << params.input_buffer_id;
+ << params.input_buffer.id();
NotifyDecodeStatusOnIOThread(
- *route_id, params.input_buffer_id,
+ *route_id, params.input_buffer.id(),
media::JpegDecodeAccelerator::PLATFORM_FAILURE);
- base::SharedMemory::CloseHandle(params.input_buffer_handle);
+ base::SharedMemory::CloseHandle(params.input_buffer.handle());
return;
}
frame->AddDestructionObserver(
@@ -262,7 +245,7 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
DCHECK_GT(client_map_.count(*route_id), 0u);
Client* client = client_map_[*route_id];
- client->Decode(input_buffer, frame);
+ client->Decode(params.input_buffer, frame);
}
protected:
@@ -309,7 +292,7 @@ class GpuJpegDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
};
GpuJpegDecodeAccelerator::GpuJpegDecodeAccelerator(
- GpuChannel* channel,
+ gpu::GpuChannel* channel,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
: channel_(channel),
child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
@@ -325,7 +308,7 @@ GpuJpegDecodeAccelerator::~GpuJpegDecodeAccelerator() {
}
void GpuJpegDecodeAccelerator::AddClient(int32_t route_id,
- IPC::Message* reply_msg) {
+ base::Callback<void(bool)> response) {
DCHECK(CalledOnValidThread());
// When adding non-chromeos platforms, VideoCaptureGpuJpegDecoder::Initialize
@@ -350,8 +333,7 @@ void GpuJpegDecodeAccelerator::AddClient(int32_t route_id,
if (!accelerator) {
DLOG(ERROR) << "JPEG accelerator Initialize failed";
- GpuMsg_CreateJpegDecoder::WriteReplyParams(reply_msg, false);
- Send(reply_msg);
+ response.Run(false);
return;
}
client->set_accelerator(std::move(accelerator));
@@ -372,7 +354,7 @@ void GpuJpegDecodeAccelerator::AddClient(int32_t route_id,
// here instead of making the code unnecessary complicated.
io_task_runner_->PostTask(
FROM_HERE, base::Bind(&MessageFilter::AddClientOnIOThread, filter_,
- route_id, client.release(), reply_msg));
+ route_id, client.release(), response));
}
void GpuJpegDecodeAccelerator::NotifyDecodeStatus(
diff --git a/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.h b/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.h
index 0fc316e026f..680dac578e0 100644
--- a/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/gpu_jpeg_decode_accelerator.h
@@ -20,9 +20,11 @@ namespace base {
class SingleThreadTaskRunner;
}
-namespace content {
+namespace gpu {
class GpuChannel;
+}
+namespace content {
class GpuJpegDecodeAccelerator
: public IPC::Sender,
public base::NonThreadSafe,
@@ -30,11 +32,11 @@ class GpuJpegDecodeAccelerator
public:
// |channel| must outlive this object.
GpuJpegDecodeAccelerator(
- GpuChannel* channel,
+ gpu::GpuChannel* channel,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
~GpuJpegDecodeAccelerator() override;
- void AddClient(int32_t route_id, IPC::Message* reply_msg);
+ void AddClient(int32_t route_id, base::Callback<void(bool)> response);
void NotifyDecodeStatus(int32_t route_id,
int32_t bitstream_buffer_id,
@@ -61,10 +63,10 @@ class GpuJpegDecodeAccelerator
static scoped_ptr<media::JpegDecodeAccelerator> CreateVaapiJDA(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
- // The lifetime of objects of this class is managed by a GpuChannel. The
+ // The lifetime of objects of this class is managed by a gpu::GpuChannel. The
// GpuChannels destroy all the GpuJpegDecodeAccelerator that they own when
// they are destroyed. So a raw pointer is safe.
- GpuChannel* channel_;
+ gpu::GpuChannel* channel_;
// The message filter to run JpegDecodeAccelerator::Decode on IO thread.
scoped_refptr<MessageFilter> filter_;
diff --git a/chromium/content/common/gpu/media/gpu_video_accelerator_util.cc b/chromium/content/common/gpu/media/gpu_video_accelerator_util.cc
deleted file mode 100644
index 7692fddc40a..00000000000
--- a/chromium/content/common/gpu/media/gpu_video_accelerator_util.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2015 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 "content/common/gpu/media/gpu_video_accelerator_util.h"
-
-namespace content {
-
-// Make sure the enum values of media::VideoCodecProfile and
-// gpu::VideoCodecProfile match.
-#define STATIC_ASSERT_ENUM_MATCH(name) \
- static_assert( \
- media::name == static_cast<media::VideoCodecProfile>(gpu::name), \
- #name " value must match in media and gpu.")
-
-STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_UNKNOWN);
-STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MIN);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_BASELINE);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MAIN);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_EXTENDED);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH10PROFILE);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH422PROFILE);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH444PREDICTIVEPROFILE);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEBASELINE);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEHIGH);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_STEREOHIGH);
-STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MULTIVIEWHIGH);
-STATIC_ASSERT_ENUM_MATCH(VP8PROFILE_ANY);
-STATIC_ASSERT_ENUM_MATCH(VP9PROFILE_ANY);
-STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MAX);
-
-// static
-media::VideoDecodeAccelerator::Capabilities
-GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeCapabilities(
- const gpu::VideoDecodeAcceleratorCapabilities& gpu_capabilities) {
- media::VideoDecodeAccelerator::Capabilities capabilities;
- capabilities.supported_profiles =
- ConvertGpuToMediaDecodeProfiles(gpu_capabilities.supported_profiles);
- capabilities.flags = gpu_capabilities.flags;
- return capabilities;
-}
-
-// static
-media::VideoDecodeAccelerator::SupportedProfiles
-GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles(const
- gpu::VideoDecodeAcceleratorSupportedProfiles& gpu_profiles) {
- media::VideoDecodeAccelerator::SupportedProfiles profiles;
- for (const auto& gpu_profile : gpu_profiles) {
- media::VideoDecodeAccelerator::SupportedProfile profile;
- profile.profile =
- static_cast<media::VideoCodecProfile>(gpu_profile.profile);
- profile.max_resolution = gpu_profile.max_resolution;
- profile.min_resolution = gpu_profile.min_resolution;
- profiles.push_back(profile);
- }
- return profiles;
-}
-
-// static
-gpu::VideoDecodeAcceleratorCapabilities
-GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities(
- const media::VideoDecodeAccelerator::Capabilities& media_capabilities) {
- gpu::VideoDecodeAcceleratorCapabilities capabilities;
- capabilities.supported_profiles =
- ConvertMediaToGpuDecodeProfiles(media_capabilities.supported_profiles);
- capabilities.flags = media_capabilities.flags;
- return capabilities;
-}
-
-// static
-gpu::VideoDecodeAcceleratorSupportedProfiles
-GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(const
- media::VideoDecodeAccelerator::SupportedProfiles& media_profiles) {
- gpu::VideoDecodeAcceleratorSupportedProfiles profiles;
- for (const auto& media_profile : media_profiles) {
- gpu::VideoDecodeAcceleratorSupportedProfile profile;
- profile.profile =
- static_cast<gpu::VideoCodecProfile>(media_profile.profile);
- profile.max_resolution = media_profile.max_resolution;
- profile.min_resolution = media_profile.min_resolution;
- profiles.push_back(profile);
- }
- return profiles;
-}
-
-// static
-media::VideoEncodeAccelerator::SupportedProfiles
-GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(const
- gpu::VideoEncodeAcceleratorSupportedProfiles& gpu_profiles) {
- media::VideoEncodeAccelerator::SupportedProfiles profiles;
- for (const auto& gpu_profile : gpu_profiles) {
- media::VideoEncodeAccelerator::SupportedProfile profile;
- profile.profile =
- static_cast<media::VideoCodecProfile>(gpu_profile.profile);
- profile.max_resolution = gpu_profile.max_resolution;
- profile.max_framerate_numerator = gpu_profile.max_framerate_numerator;
- profile.max_framerate_denominator = gpu_profile.max_framerate_denominator;
- profiles.push_back(profile);
- }
- return profiles;
-}
-
-// static
-gpu::VideoEncodeAcceleratorSupportedProfiles
-GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(const
- media::VideoEncodeAccelerator::SupportedProfiles& media_profiles) {
- gpu::VideoEncodeAcceleratorSupportedProfiles profiles;
- for (const auto& media_profile : media_profiles) {
- gpu::VideoEncodeAcceleratorSupportedProfile profile;
- profile.profile =
- static_cast<gpu::VideoCodecProfile>(media_profile.profile);
- profile.max_resolution = media_profile.max_resolution;
- profile.max_framerate_numerator = media_profile.max_framerate_numerator;
- profile.max_framerate_denominator = media_profile.max_framerate_denominator;
- profiles.push_back(profile);
- }
- return profiles;
-}
-
-// static
-void GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
- const media::VideoDecodeAccelerator::SupportedProfiles& new_profiles,
- media::VideoDecodeAccelerator::SupportedProfiles* media_profiles) {
- for (const auto& profile : new_profiles) {
- bool duplicate = false;
- for (const auto& media_profile : *media_profiles) {
- if (media_profile.profile == profile.profile) {
- duplicate = true;
- break;
- }
- }
- if (!duplicate)
- media_profiles->push_back(profile);
- }
-}
-
-// static
-void GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(
- const media::VideoEncodeAccelerator::SupportedProfiles& new_profiles,
- media::VideoEncodeAccelerator::SupportedProfiles* media_profiles) {
- for (const auto& profile : new_profiles) {
- bool duplicate = false;
- for (const auto& media_profile : *media_profiles) {
- if (media_profile.profile == profile.profile) {
- duplicate = true;
- break;
- }
- }
- if (!duplicate)
- media_profiles->push_back(profile);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/media/gpu_video_accelerator_util.h b/chromium/content/common/gpu/media/gpu_video_accelerator_util.h
deleted file mode 100644
index e39034e191e..00000000000
--- a/chromium/content/common/gpu/media/gpu_video_accelerator_util.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_
-#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_
-
-#include <vector>
-
-#include "gpu/config/gpu_info.h"
-#include "media/video/video_decode_accelerator.h"
-#include "media/video/video_encode_accelerator.h"
-
-namespace content {
-
-class GpuVideoAcceleratorUtil {
- public:
- // Convert decoder gpu capabilities to media capabilities.
- static media::VideoDecodeAccelerator::Capabilities
- ConvertGpuToMediaDecodeCapabilities(
- const gpu::VideoDecodeAcceleratorCapabilities& gpu_capabilities);
-
- // Convert decoder gpu profiles to media profiles.
- static media::VideoDecodeAccelerator::SupportedProfiles
- ConvertGpuToMediaDecodeProfiles(const
- gpu::VideoDecodeAcceleratorSupportedProfiles& gpu_profiles);
-
- // Convert decoder media capabilities to gpu capabilities.
- static gpu::VideoDecodeAcceleratorCapabilities
- ConvertMediaToGpuDecodeCapabilities(
- const media::VideoDecodeAccelerator::Capabilities& media_capabilities);
-
- // Convert decoder media profiles to gpu profiles.
- static gpu::VideoDecodeAcceleratorSupportedProfiles
- ConvertMediaToGpuDecodeProfiles(const
- media::VideoDecodeAccelerator::SupportedProfiles& media_profiles);
-
- // Convert encoder gpu profiles to media profiles.
- static media::VideoEncodeAccelerator::SupportedProfiles
- ConvertGpuToMediaEncodeProfiles(const
- gpu::VideoEncodeAcceleratorSupportedProfiles& gpu_profiles);
-
- // Convert encoder media profiles to gpu profiles.
- static gpu::VideoEncodeAcceleratorSupportedProfiles
- ConvertMediaToGpuEncodeProfiles(const
- media::VideoEncodeAccelerator::SupportedProfiles& media_profiles);
-
- // Insert |new_profiles| into |media_profiles|, ensuring no duplicates are
- // inserted.
- static void InsertUniqueDecodeProfiles(
- const media::VideoDecodeAccelerator::SupportedProfiles& new_profiles,
- media::VideoDecodeAccelerator::SupportedProfiles* media_profiles);
-
- // Insert |new_profiles| into |media_profiles|, ensuring no duplicates are
- // inserted.
- static void InsertUniqueEncodeProfiles(
- const media::VideoEncodeAccelerator::SupportedProfiles& new_profiles,
- media::VideoEncodeAccelerator::SupportedProfiles* media_profiles);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_
diff --git a/chromium/content/common/gpu/media/gpu_video_decode_accelerator.cc b/chromium/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 5424a5ff32d..3d30266f05a 100644
--- a/chromium/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -7,7 +7,6 @@
#include <vector>
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
@@ -15,47 +14,36 @@
#include "base/stl_util.h"
#include "base/thread_task_runner_handle.h"
#include "build/build_config.h"
-
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/media/gpu_video_accelerator_util.h"
-#include "content/public/common/content_switches.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h"
#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/ipc/service/gpu_channel.h"
+#include "gpu/ipc/service/gpu_channel_manager.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/message_filter.h"
#include "media/base/limits.h"
+#include "media/gpu/ipc/common/gpu_video_accelerator_util.h"
+#include "media/gpu/ipc/common/media_messages.h"
+#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image.h"
-#include "ui/gl/gl_surface_egl.h"
-
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h"
-#elif defined(OS_MACOSX)
-#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h"
-#elif defined(OS_CHROMEOS)
-#if defined(USE_V4L2_CODEC)
-#include "content/common/gpu/media/v4l2_device.h"
-#include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h"
-#include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
-#endif
-#if defined(ARCH_CPU_X86_FAMILY)
-#include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
-#include "ui/gl/gl_implementation.h"
-#endif
-#elif defined(USE_OZONE)
-#include "media/ozone/media_ozone_platform.h"
-#elif defined(OS_ANDROID)
-#include "content/common/gpu/media/android_video_decode_accelerator.h"
-#endif
-
-#include "ui/gfx/geometry/size.h"
namespace content {
+namespace {
+static gfx::GLContext* GetGLContext(
+ const base::WeakPtr<gpu::GpuCommandBufferStub>& stub) {
+ if (!stub) {
+ DLOG(ERROR) << "Stub is gone; no GLContext.";
+ return nullptr;
+ }
+
+ return stub->decoder()->GetGLContext();
+}
+
static bool MakeDecoderContextCurrent(
- const base::WeakPtr<GpuCommandBufferStub> stub) {
+ const base::WeakPtr<gpu::GpuCommandBufferStub>& stub) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
return false;
@@ -69,6 +57,43 @@ static bool MakeDecoderContextCurrent(
return true;
}
+#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX)
+static bool BindImage(const base::WeakPtr<gpu::GpuCommandBufferStub>& stub,
+ uint32_t client_texture_id,
+ uint32_t texture_target,
+ const scoped_refptr<gl::GLImage>& image,
+ bool can_bind_to_sampler) {
+ if (!stub) {
+ DLOG(ERROR) << "Stub is gone; won't BindImage().";
+ return false;
+ }
+
+ gpu::gles2::GLES2Decoder* command_decoder = stub->decoder();
+ gpu::gles2::TextureManager* texture_manager =
+ command_decoder->GetContextGroup()->texture_manager();
+ gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id);
+ if (ref) {
+ texture_manager->SetLevelImage(ref, texture_target, 0, image.get(),
+ can_bind_to_sampler
+ ? gpu::gles2::Texture::BOUND
+ : gpu::gles2::Texture::UNBOUND);
+ }
+
+ return true;
+}
+#endif
+
+static base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder(
+ const base::WeakPtr<gpu::GpuCommandBufferStub>& stub) {
+ if (!stub) {
+ DLOG(ERROR) << "Stub is gone; no GLES2Decoder.";
+ return base::WeakPtr<gpu::gles2::GLES2Decoder>();
+ }
+
+ return stub->decoder()->AsWeakPtr();
+}
+} // anonymous namespace
+
// DebugAutoLock works like AutoLock but only acquires the lock when
// DCHECK is on.
#if DCHECK_IS_ON()
@@ -103,7 +128,7 @@ class GpuVideoDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
IPC_BEGIN_MESSAGE_MAP(MessageFilter, msg)
IPC_MESSAGE_FORWARD(AcceleratedVideoDecoderMsg_Decode, owner_,
GpuVideoDecodeAccelerator::OnDecode)
- IPC_MESSAGE_UNHANDLED(return false;)
+ IPC_MESSAGE_UNHANDLED(return false)
IPC_END_MESSAGE_MAP()
return true;
}
@@ -129,19 +154,25 @@ class GpuVideoDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(
int32_t host_route_id,
- GpuCommandBufferStub* stub,
+ gpu::GpuCommandBufferStub* stub,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
: host_route_id_(host_route_id),
stub_(stub),
texture_target_(0),
+ textures_per_buffer_(0),
filter_removed_(true, false),
child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
io_task_runner_(io_task_runner),
weak_factory_for_io_(this) {
DCHECK(stub_);
stub_->AddDestructionObserver(this);
- make_context_current_ =
+ get_gl_context_cb_ = base::Bind(&GetGLContext, stub_->AsWeakPtr());
+ make_context_current_cb_ =
base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
+#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX)
+ bind_image_cb_ = base::Bind(&BindImage, stub_->AsWeakPtr());
+#endif
+ get_gles2_decoder_cb_ = base::Bind(&GetGLES2Decoder, stub_->AsWeakPtr());
}
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
@@ -152,41 +183,10 @@ GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
// static
gpu::VideoDecodeAcceleratorCapabilities
-GpuVideoDecodeAccelerator::GetCapabilities() {
- media::VideoDecodeAccelerator::Capabilities capabilities;
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- if (cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
- return gpu::VideoDecodeAcceleratorCapabilities();
-
- // Query supported profiles for each VDA. The order of querying VDAs should
- // be the same as the order of initializing VDAs. Then the returned profile
- // can be initialized by corresponding VDA successfully.
-#if defined(OS_WIN)
- capabilities.supported_profiles =
- DXVAVideoDecodeAccelerator::GetSupportedProfiles();
-#elif defined(OS_CHROMEOS)
- media::VideoDecodeAccelerator::SupportedProfiles vda_profiles;
-#if defined(USE_V4L2_CODEC)
- vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles();
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
- vda_profiles, &capabilities.supported_profiles);
- vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
- vda_profiles, &capabilities.supported_profiles);
-#endif
-#if defined(ARCH_CPU_X86_FAMILY)
- vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles();
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
- vda_profiles, &capabilities.supported_profiles);
-#endif
-#elif defined(OS_MACOSX)
- capabilities.supported_profiles =
- VTVideoDecodeAccelerator::GetSupportedProfiles();
-#elif defined(OS_ANDROID)
- capabilities = AndroidVideoDecodeAccelerator::GetCapabilities();
-#endif
- return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities(
- capabilities);
+GpuVideoDecodeAccelerator::GetCapabilities(
+ const gpu::GpuPreferences& gpu_preferences) {
+ return GpuVideoDecodeAcceleratorFactoryImpl::GetDecoderCapabilities(
+ gpu_preferences);
}
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
@@ -209,14 +209,16 @@ bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
-void GpuVideoDecodeAccelerator::NotifyCdmAttached(bool success) {
- if (!Send(new AcceleratedVideoDecoderHostMsg_CdmAttached(host_route_id_,
- success)))
- DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_CdmAttached) failed";
+void GpuVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
+ if (!Send(new AcceleratedVideoDecoderHostMsg_InitializationComplete(
+ host_route_id_, success)))
+ DLOG(ERROR)
+ << "Send(AcceleratedVideoDecoderHostMsg_InitializationComplete) failed";
}
void GpuVideoDecodeAccelerator::ProvidePictureBuffers(
uint32_t requested_num_of_buffers,
+ uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) {
if (dimensions.width() > media::limits::kMaxDimension ||
@@ -226,14 +228,13 @@ void GpuVideoDecodeAccelerator::ProvidePictureBuffers(
return;
}
if (!Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers(
- host_route_id_,
- requested_num_of_buffers,
- dimensions,
- texture_target))) {
+ host_route_id_, requested_num_of_buffers, textures_per_buffer,
+ dimensions, texture_target))) {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers) "
<< "failed";
}
texture_dimensions_ = dimensions;
+ textures_per_buffer_ = textures_per_buffer;
texture_target_ = texture_target;
}
@@ -265,7 +266,7 @@ void GpuVideoDecodeAccelerator::PictureReady(
if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
host_route_id_, picture.picture_buffer_id(),
picture.bitstream_buffer_id(), picture.visible_rect(),
- picture.allow_overlay()))) {
+ picture.allow_overlay(), picture.size_changed()))) {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
}
}
@@ -327,161 +328,51 @@ bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
return stub_->channel()->Send(message);
}
-void GpuVideoDecodeAccelerator::Initialize(
- const media::VideoDecodeAccelerator::Config& config,
- IPC::Message* init_done_msg) {
+bool GpuVideoDecodeAccelerator::Initialize(
+ const media::VideoDecodeAccelerator::Config& config) {
DCHECK(!video_decode_accelerator_);
- if (!stub_->channel()->AddRoute(host_route_id_, this)) {
+ if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) {
DLOG(ERROR) << "Initialize(): failed to add route";
- SendCreateDecoderReply(init_done_msg, false);
+ return false;
}
#if !defined(OS_WIN)
// Ensure we will be able to get a GL context at all before initializing
// non-Windows VDAs.
- if (!make_context_current_.Run()) {
- SendCreateDecoderReply(init_done_msg, false);
- return;
- }
+ if (!make_context_current_cb_.Run())
+ return false;
#endif
- // Array of Create..VDA() function pointers, maybe applicable to the current
- // platform. This list is ordered by priority of use and it should be the
- // same as the order of querying supported profiles of VDAs.
- const GpuVideoDecodeAccelerator::CreateVDAFp create_vda_fps[] = {
- &GpuVideoDecodeAccelerator::CreateDXVAVDA,
- &GpuVideoDecodeAccelerator::CreateV4L2VDA,
- &GpuVideoDecodeAccelerator::CreateV4L2SliceVDA,
- &GpuVideoDecodeAccelerator::CreateVaapiVDA,
- &GpuVideoDecodeAccelerator::CreateVTVDA,
- &GpuVideoDecodeAccelerator::CreateOzoneVDA,
- &GpuVideoDecodeAccelerator::CreateAndroidVDA};
-
- for (const auto& create_vda_function : create_vda_fps) {
- video_decode_accelerator_ = (this->*create_vda_function)();
- if (!video_decode_accelerator_ ||
- !video_decode_accelerator_->Initialize(config, this))
- continue;
-
- if (video_decode_accelerator_->CanDecodeOnIOThread()) {
- filter_ = new MessageFilter(this, host_route_id_);
- stub_->channel()->AddFilter(filter_.get());
- }
- SendCreateDecoderReply(init_done_msg, true);
- return;
- }
- video_decode_accelerator_.reset();
- LOG(ERROR) << "HW video decode not available for profile " << config.profile
- << (config.is_encrypted ? " with encryption" : "");
- SendCreateDecoderReply(init_done_msg, false);
-}
+ scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> vda_factory =
+ GpuVideoDecodeAcceleratorFactoryImpl::CreateWithGLES2Decoder(
+ get_gl_context_cb_, make_context_current_cb_, bind_image_cb_,
+ get_gles2_decoder_cb_);
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateDXVAVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_WIN)
- if (base::win::GetVersion() >= base::win::VERSION_WIN7) {
- DVLOG(0) << "Initializing DXVA HW decoder for windows.";
- decoder.reset(new DXVAVideoDecodeAccelerator(make_context_current_,
- stub_->decoder()->GetGLContext()));
- } else {
- NOTIMPLEMENTED() << "HW video decode acceleration not available.";
+ if (!vda_factory) {
+ LOG(ERROR) << "Failed creating the VDA factory";
+ return false;
}
-#endif
- return decoder;
-}
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateV4L2VDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
- if (device.get()) {
- decoder.reset(new V4L2VideoDecodeAccelerator(
- gfx::GLSurfaceEGL::GetHardwareDisplay(),
- stub_->decoder()->GetGLContext()->GetHandle(),
- weak_factory_for_io_.GetWeakPtr(),
- make_context_current_,
- device,
- io_task_runner_));
+ const gpu::GpuPreferences& gpu_preferences =
+ stub_->channel()->gpu_channel_manager()->gpu_preferences();
+ video_decode_accelerator_ =
+ vda_factory->CreateVDA(this, config, gpu_preferences);
+ if (!video_decode_accelerator_) {
+ LOG(ERROR) << "HW video decode not available for profile " << config.profile
+ << (config.is_encrypted ? " with encryption" : "");
+ return false;
}
-#endif
- return decoder;
-}
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
- if (device.get()) {
- decoder.reset(new V4L2SliceVideoDecodeAccelerator(
- device,
- gfx::GLSurfaceEGL::GetHardwareDisplay(),
- stub_->decoder()->GetGLContext()->GetHandle(),
- weak_factory_for_io_.GetWeakPtr(),
- make_context_current_,
- io_task_runner_));
+ // Attempt to set up performing decoding tasks on IO thread, if supported by
+ // the VDA.
+ if (video_decode_accelerator_->TryToSetupDecodeOnSeparateThread(
+ weak_factory_for_io_.GetWeakPtr(), io_task_runner_)) {
+ filter_ = new MessageFilter(this, host_route_id_);
+ stub_->channel()->AddFilter(filter_.get());
}
-#endif
- return decoder;
-}
-void GpuVideoDecodeAccelerator::BindImage(uint32_t client_texture_id,
- uint32_t texture_target,
- scoped_refptr<gl::GLImage> image) {
- gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder();
- gpu::gles2::TextureManager* texture_manager =
- command_decoder->GetContextGroup()->texture_manager();
- gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id);
- if (ref) {
- texture_manager->SetLevelImage(ref, texture_target, 0, image.get(),
- gpu::gles2::Texture::BOUND);
- }
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateVaapiVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
- decoder.reset(new VaapiVideoDecodeAccelerator(
- make_context_current_, base::Bind(&GpuVideoDecodeAccelerator::BindImage,
- base::Unretained(this))));
-#endif
- return decoder;
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateVTVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_MACOSX)
- decoder.reset(new VTVideoDecodeAccelerator(
- make_context_current_, base::Bind(&GpuVideoDecodeAccelerator::BindImage,
- base::Unretained(this))));
-#endif
- return decoder;
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateOzoneVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if !defined(OS_CHROMEOS) && defined(USE_OZONE)
- media::MediaOzonePlatform* platform =
- media::MediaOzonePlatform::GetInstance();
- decoder.reset(platform->CreateVideoDecodeAccelerator(make_context_current_));
-#endif
- return decoder;
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GpuVideoDecodeAccelerator::CreateAndroidVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_ANDROID)
- decoder.reset(new AndroidVideoDecodeAccelerator(stub_->decoder()->AsWeakPtr(),
- make_context_current_));
-#endif
- return decoder;
+ return true;
}
void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) {
@@ -489,40 +380,17 @@ void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) {
video_decode_accelerator_->SetCdm(cdm_id);
}
-// Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is
-// true, otherwise on the main thread.
+// Runs on IO thread if VDA::TryToSetupDecodeOnSeparateThread() succeeded,
+// otherwise on the main thread.
void GpuVideoDecodeAccelerator::OnDecode(
- const AcceleratedVideoDecoderMsg_Decode_Params& params) {
+ const media::BitstreamBuffer& bitstream_buffer) {
DCHECK(video_decode_accelerator_);
- if (params.bitstream_buffer_id < 0) {
- DLOG(ERROR) << "BitstreamBuffer id " << params.bitstream_buffer_id
- << " out of range";
- if (child_task_runner_->BelongsToCurrentThread()) {
- NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
- } else {
- child_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GpuVideoDecodeAccelerator::NotifyError,
- base::Unretained(this),
- media::VideoDecodeAccelerator::INVALID_ARGUMENT));
- }
- return;
- }
-
- media::BitstreamBuffer bitstream_buffer(params.bitstream_buffer_id,
- params.buffer_handle, params.size,
- params.presentation_timestamp);
- if (!params.key_id.empty()) {
- bitstream_buffer.SetDecryptConfig(
- media::DecryptConfig(params.key_id, params.iv, params.subsamples));
- }
-
video_decode_accelerator_->Decode(bitstream_buffer);
}
void GpuVideoDecodeAccelerator::OnAssignPictureBuffers(
const std::vector<int32_t>& buffer_ids,
- const std::vector<uint32_t>& texture_ids) {
+ const std::vector<media::PictureBuffer::TextureIds>& texture_ids) {
if (buffer_ids.size() != texture_ids.size()) {
NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
@@ -540,51 +408,65 @@ void GpuVideoDecodeAccelerator::OnAssignPictureBuffers(
NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
- gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture(
- texture_ids[i]);
- if (!texture_ref) {
- DLOG(ERROR) << "Failed to find texture id " << texture_ids[i];
- NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
- return;
- }
- gpu::gles2::Texture* info = texture_ref->texture();
- if (info->target() != texture_target_) {
- DLOG(ERROR) << "Texture target mismatch for texture id "
- << texture_ids[i];
+ media::PictureBuffer::TextureIds buffer_texture_ids = texture_ids[i];
+ media::PictureBuffer::TextureIds service_ids;
+ if (buffer_texture_ids.size() != textures_per_buffer_) {
+ DLOG(ERROR) << "Requested " << textures_per_buffer_
+ << " textures per picture buffer, got "
+ << buffer_texture_ids.size();
NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
- if (texture_target_ == GL_TEXTURE_EXTERNAL_OES ||
- texture_target_ == GL_TEXTURE_RECTANGLE_ARB) {
- // These textures have their dimensions defined by the underlying storage.
- // Use |texture_dimensions_| for this size.
- texture_manager->SetLevelInfo(
- texture_ref, texture_target_, 0, GL_RGBA, texture_dimensions_.width(),
- texture_dimensions_.height(), 1, 0, GL_RGBA, 0, gfx::Rect());
- } else {
- // For other targets, texture dimensions should already be defined.
- GLsizei width = 0, height = 0;
- info->GetLevelSize(texture_target_, 0, &width, &height, nullptr);
- if (width != texture_dimensions_.width() ||
- height != texture_dimensions_.height()) {
- DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i];
+ for (size_t j = 0; j < textures_per_buffer_; j++) {
+ gpu::gles2::TextureRef* texture_ref =
+ texture_manager->GetTexture(buffer_texture_ids[j]);
+ if (!texture_ref) {
+ DLOG(ERROR) << "Failed to find texture id " << buffer_texture_ids[j];
NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
-
- // TODO(dshwang): after moving to D3D11, remove this. crbug.com/438691
- GLenum format =
- video_decode_accelerator_.get()->GetSurfaceInternalFormat();
- if (format != GL_RGBA) {
- texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, format,
- width, height, 1, 0, format, 0,
- gfx::Rect());
+ gpu::gles2::Texture* info = texture_ref->texture();
+ if (info->target() != texture_target_) {
+ DLOG(ERROR) << "Texture target mismatch for texture id "
+ << buffer_texture_ids[j];
+ NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
+ return;
+ }
+ if (texture_target_ == GL_TEXTURE_EXTERNAL_OES ||
+ texture_target_ == GL_TEXTURE_RECTANGLE_ARB) {
+ // These textures have their dimensions defined by the underlying
+ // storage.
+ // Use |texture_dimensions_| for this size.
+ texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, GL_RGBA,
+ texture_dimensions_.width(),
+ texture_dimensions_.height(), 1, 0,
+ GL_RGBA, 0, gfx::Rect());
+ } else {
+ // For other targets, texture dimensions should already be defined.
+ GLsizei width = 0, height = 0;
+ info->GetLevelSize(texture_target_, 0, &width, &height, nullptr);
+ if (width != texture_dimensions_.width() ||
+ height != texture_dimensions_.height()) {
+ DLOG(ERROR) << "Size mismatch for texture id "
+ << buffer_texture_ids[j];
+ NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
+ return;
+ }
+
+ // TODO(dshwang): after moving to D3D11, remove this. crbug.com/438691
+ GLenum format =
+ video_decode_accelerator_.get()->GetSurfaceInternalFormat();
+ if (format != GL_RGBA) {
+ texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, format,
+ width, height, 1, 0, format, 0,
+ gfx::Rect());
+ }
}
+ service_ids.push_back(texture_ref->service_id());
+ textures.push_back(texture_ref);
}
buffers.push_back(media::PictureBuffer(buffer_ids[i], texture_dimensions_,
- texture_ref->service_id(),
- texture_ids[i]));
- textures.push_back(texture_ref);
+ service_ids, buffer_texture_ids));
}
video_decode_accelerator_->AssignPictureBuffers(buffers);
DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
@@ -637,10 +519,4 @@ void GpuVideoDecodeAccelerator::SetTextureCleared(
uncleared_textures_.erase(it);
}
-void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message,
- bool succeeded) {
- GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded);
- Send(message);
-}
-
} // namespace content
diff --git a/chromium/content/common/gpu/media/gpu_video_decode_accelerator.h b/chromium/content/common/gpu/media/gpu_video_decode_accelerator.h
index eb6459b37c3..47859d957f9 100644
--- a/chromium/content/common/gpu/media/gpu_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -15,15 +15,19 @@
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/synchronization/waitable_event.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/ipc/service/gpu_command_buffer_stub.h"
+#include "gpu/ipc/service/gpu_command_buffer_stub.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "media/video/video_decode_accelerator.h"
#include "ui/gfx/geometry/size.h"
-struct AcceleratedVideoDecoderMsg_Decode_Params;
+namespace gpu {
+struct GpuPreferences;
+} // namespace gpu
namespace content {
@@ -31,27 +35,29 @@ class GpuVideoDecodeAccelerator
: public IPC::Listener,
public IPC::Sender,
public media::VideoDecodeAccelerator::Client,
- public GpuCommandBufferStub::DestructionObserver {
+ public gpu::GpuCommandBufferStub::DestructionObserver {
public:
// Each of the arguments to the constructor must outlive this object.
// |stub->decoder()| will be made current around any operation that touches
// the underlying VDA so that it can make GL calls safely.
GpuVideoDecodeAccelerator(
int32_t host_route_id,
- GpuCommandBufferStub* stub,
+ gpu::GpuCommandBufferStub* stub,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
// Static query for the capabilities, which includes the supported profiles.
// This query calls the appropriate platform-specific version. The returned
// capabilities will not contain duplicate supported profile entries.
- static gpu::VideoDecodeAcceleratorCapabilities GetCapabilities();
+ static gpu::VideoDecodeAcceleratorCapabilities GetCapabilities(
+ const gpu::GpuPreferences& gpu_preferences);
// IPC::Listener implementation.
bool OnMessageReceived(const IPC::Message& message) override;
// media::VideoDecodeAccelerator::Client implementation.
- void NotifyCdmAttached(bool success) override;
+ void NotifyInitializationComplete(bool success) override;
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
+ uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
void DismissPictureBuffer(int32_t picture_buffer_id) override;
@@ -69,33 +75,22 @@ class GpuVideoDecodeAccelerator
// Initialize VDAs from the set of VDAs supported for current platform until
// one of them succeeds for given |config|. Send the |init_done_msg| when
- // done. filter_ is passed to GpuCommandBufferStub channel only if the chosen
- // VDA can decode on IO thread.
- void Initialize(const media::VideoDecodeAccelerator::Config& config,
- IPC::Message* init_done_msg);
+ // done. filter_ is passed to gpu::GpuCommandBufferStub channel only if the
+ // chosen VDA can decode on IO thread.
+ bool Initialize(const media::VideoDecodeAccelerator::Config& config);
private:
- typedef scoped_ptr<media::VideoDecodeAccelerator>(
- GpuVideoDecodeAccelerator::*CreateVDAFp)();
-
class MessageFilter;
- scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SliceVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateVTVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateOzoneVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateAndroidVDA();
-
// We only allow self-delete, from OnWillDestroyStub(), after cleanup there.
~GpuVideoDecodeAccelerator() override;
// Handlers for IPC messages.
void OnSetCdm(int cdm_id);
- void OnDecode(const AcceleratedVideoDecoderMsg_Decode_Params& params);
- void OnAssignPictureBuffers(const std::vector<int32_t>& buffer_ids,
- const std::vector<uint32_t>& texture_ids);
+ void OnDecode(const media::BitstreamBuffer& bitstream_buffer);
+ void OnAssignPictureBuffers(
+ const std::vector<int32_t>& buffer_ids,
+ const std::vector<media::PictureBuffer::TextureIds>& texture_ids);
void OnReusePictureBuffer(int32_t picture_buffer_id);
void OnFlush();
void OnReset();
@@ -107,28 +102,28 @@ class GpuVideoDecodeAccelerator
// Sets the texture to cleared.
void SetTextureCleared(const media::Picture& picture);
- // Helper for replying to the creation request.
- void SendCreateDecoderReply(IPC::Message* message, bool succeeded);
-
- // Helper to bind |image| to the texture specified by |client_texture_id|.
- void BindImage(uint32_t client_texture_id,
- uint32_t texture_target,
- scoped_refptr<gl::GLImage> image);
-
// Route ID to communicate with the host.
const int32_t host_route_id_;
- // Unowned pointer to the underlying GpuCommandBufferStub. |this| is
+ // Unowned pointer to the underlying gpu::GpuCommandBufferStub. |this| is
// registered as a DestuctionObserver of |stub_| and will self-delete when
// |stub_| is destroyed.
- GpuCommandBufferStub* const stub_;
+ gpu::GpuCommandBufferStub* const stub_;
// The underlying VideoDecodeAccelerator.
scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_;
+ // Callback to return current GLContext, if available.
+ GetGLContextCallback get_gl_context_cb_;
+
// Callback for making the relevant context current for GL calls.
- // Returns false if failed.
- base::Callback<bool(void)> make_context_current_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
+
+ // Callback to bind a GLImage to a given texture id and target.
+ BindGLImageCallback bind_image_cb_;
+
+ // Callback to return a WeakPtr to GLES2Decoder.
+ GetGLES2DecoderCallback get_gles2_decoder_cb_;
// The texture dimensions as requested by ProvidePictureBuffers().
gfx::Size texture_dimensions_;
@@ -136,6 +131,10 @@ class GpuVideoDecodeAccelerator
// The texture target as requested by ProvidePictureBuffers().
uint32_t texture_target_;
+ // The number of textures per picture buffer as requests by
+ // ProvidePictureBuffers()
+ uint32_t textures_per_buffer_;
+
// The message filter to run VDA::Decode on IO thread if VDA supports it.
scoped_refptr<MessageFilter> filter_;
diff --git a/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc
new file mode 100644
index 00000000000..048314863d9
--- /dev/null
+++ b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc
@@ -0,0 +1,242 @@
+// Copyright 2016 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 "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h"
+
+#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "media/gpu/ipc/common/gpu_video_accelerator_util.h"
+
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h"
+#elif defined(OS_MACOSX)
+#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h"
+#elif defined(OS_CHROMEOS)
+#if defined(USE_V4L2_CODEC)
+#include "content/common/gpu/media/v4l2_device.h"
+#include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h"
+#include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
+#include "ui/gl/gl_surface_egl.h"
+#endif
+#if defined(ARCH_CPU_X86_FAMILY)
+#include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
+#include "ui/gl/gl_implementation.h"
+#endif
+#elif defined(OS_ANDROID)
+#include "content/common/gpu/media/android_video_decode_accelerator.h"
+#endif
+
+namespace content {
+
+namespace {
+static base::WeakPtr<gpu::gles2::GLES2Decoder> GetEmptyGLES2Decoder() {
+ NOTREACHED() << "VDA requests a GLES2Decoder, but client did not provide it";
+ return base::WeakPtr<gpu::gles2::GLES2Decoder>();
+}
+}
+
+// static
+scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl>
+GpuVideoDecodeAcceleratorFactoryImpl::Create(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb) {
+ return make_scoped_ptr(new GpuVideoDecodeAcceleratorFactoryImpl(
+ get_gl_context_cb, make_context_current_cb, bind_image_cb,
+ base::Bind(&GetEmptyGLES2Decoder)));
+}
+
+// static
+scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateWithGLES2Decoder(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb) {
+ return make_scoped_ptr(new GpuVideoDecodeAcceleratorFactoryImpl(
+ get_gl_context_cb, make_context_current_cb, bind_image_cb,
+ get_gles2_decoder_cb));
+}
+
+// static
+gpu::VideoDecodeAcceleratorCapabilities
+GpuVideoDecodeAcceleratorFactoryImpl::GetDecoderCapabilities(
+ const gpu::GpuPreferences& gpu_preferences) {
+ media::VideoDecodeAccelerator::Capabilities capabilities;
+ if (gpu_preferences.disable_accelerated_video_decode)
+ return gpu::VideoDecodeAcceleratorCapabilities();
+
+ // Query VDAs for their capabilities and construct a set of supported
+ // profiles for current platform. This must be done in the same order as in
+ // CreateVDA(), as we currently preserve additional capabilities (such as
+ // resolutions supported) only for the first VDA supporting the given codec
+ // profile (instead of calculating a superset).
+ // TODO(posciak,henryhsu): improve this so that we choose a superset of
+ // resolutions and other supported profile parameters.
+#if defined(OS_WIN)
+ capabilities.supported_profiles =
+ DXVAVideoDecodeAccelerator::GetSupportedProfiles();
+#elif defined(OS_CHROMEOS)
+ media::VideoDecodeAccelerator::SupportedProfiles vda_profiles;
+#if defined(USE_V4L2_CODEC)
+ vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles();
+ media::GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
+ vda_profiles, &capabilities.supported_profiles);
+ vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles();
+ media::GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
+ vda_profiles, &capabilities.supported_profiles);
+#endif
+#if defined(ARCH_CPU_X86_FAMILY)
+ vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles();
+ media::GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
+ vda_profiles, &capabilities.supported_profiles);
+#endif
+#elif defined(OS_MACOSX)
+ capabilities.supported_profiles =
+ VTVideoDecodeAccelerator::GetSupportedProfiles();
+#elif defined(OS_ANDROID)
+ capabilities =
+ AndroidVideoDecodeAccelerator::GetCapabilities(gpu_preferences);
+#endif
+ return media::GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities(
+ capabilities);
+}
+
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateVDA(
+ media::VideoDecodeAccelerator::Client* client,
+ const media::VideoDecodeAccelerator::Config& config,
+ const gpu::GpuPreferences& gpu_preferences) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (gpu_preferences.disable_accelerated_video_decode)
+ return nullptr;
+
+ // Array of Create..VDA() function pointers, potentially usable on current
+ // platform. This list is ordered by priority, from most to least preferred,
+ // if applicable. This list must be in the same order as the querying order
+ // in GetDecoderCapabilities() above.
+ using CreateVDAFp = scoped_ptr<media::VideoDecodeAccelerator> (
+ GpuVideoDecodeAcceleratorFactoryImpl::*)(const gpu::GpuPreferences&)
+ const;
+ const CreateVDAFp create_vda_fps[] = {
+#if defined(OS_WIN)
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateDXVAVDA,
+#endif
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2VDA,
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2SVDA,
+#endif
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateVaapiVDA,
+#endif
+#if defined(OS_MACOSX)
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateVTVDA,
+#endif
+#if defined(OS_ANDROID)
+ &GpuVideoDecodeAcceleratorFactoryImpl::CreateAndroidVDA,
+#endif
+ };
+
+ scoped_ptr<media::VideoDecodeAccelerator> vda;
+
+ for (const auto& create_vda_function : create_vda_fps) {
+ vda = (this->*create_vda_function)(gpu_preferences);
+ if (vda && vda->Initialize(config, client))
+ return vda;
+ }
+
+ return nullptr;
+}
+
+#if defined(OS_WIN)
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateDXVAVDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ if (base::win::GetVersion() >= base::win::VERSION_WIN7) {
+ DVLOG(0) << "Initializing DXVA HW decoder for windows.";
+ decoder.reset(new DXVAVideoDecodeAccelerator(
+ get_gl_context_cb_, make_context_current_cb_,
+ gpu_preferences.enable_accelerated_vpx_decode));
+ }
+ return decoder;
+}
+#endif
+
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2VDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
+ if (device.get()) {
+ decoder.reset(new V4L2VideoDecodeAccelerator(
+ gfx::GLSurfaceEGL::GetHardwareDisplay(), get_gl_context_cb_,
+ make_context_current_cb_, device));
+ }
+ return decoder;
+}
+
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2SVDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
+ if (device.get()) {
+ decoder.reset(new V4L2SliceVideoDecodeAccelerator(
+ device, gfx::GLSurfaceEGL::GetHardwareDisplay(), get_gl_context_cb_,
+ make_context_current_cb_));
+ }
+ return decoder;
+}
+#endif
+
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateVaapiVDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ decoder.reset(new VaapiVideoDecodeAccelerator(make_context_current_cb_,
+ bind_image_cb_));
+ return decoder;
+}
+#endif
+
+#if defined(OS_MACOSX)
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateVTVDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ decoder.reset(
+ new VTVideoDecodeAccelerator(make_context_current_cb_, bind_image_cb_));
+ return decoder;
+}
+#endif
+
+#if defined(OS_ANDROID)
+scoped_ptr<media::VideoDecodeAccelerator>
+GpuVideoDecodeAcceleratorFactoryImpl::CreateAndroidVDA(
+ const gpu::GpuPreferences& gpu_preferences) const {
+ scoped_ptr<media::VideoDecodeAccelerator> decoder;
+ decoder.reset(new AndroidVideoDecodeAccelerator(make_context_current_cb_,
+ get_gles2_decoder_cb_));
+ return decoder;
+}
+#endif
+
+GpuVideoDecodeAcceleratorFactoryImpl::GpuVideoDecodeAcceleratorFactoryImpl(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb)
+ : get_gl_context_cb_(get_gl_context_cb),
+ make_context_current_cb_(make_context_current_cb),
+ bind_image_cb_(bind_image_cb),
+ get_gles2_decoder_cb_(get_gles2_decoder_cb) {}
+
+GpuVideoDecodeAcceleratorFactoryImpl::~GpuVideoDecodeAcceleratorFactoryImpl() {}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h
new file mode 100644
index 00000000000..2d4c10b8c32
--- /dev/null
+++ b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h
@@ -0,0 +1,123 @@
+// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_
+#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_
+
+#include "base/callback.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/config/gpu_info.h"
+#include "media/video/video_decode_accelerator.h"
+
+namespace gfx {
+class GLContext;
+}
+
+namespace gl {
+class GLImage;
+}
+
+namespace gpu {
+struct GpuPreferences;
+
+namespace gles2 {
+class GLES2Decoder;
+}
+}
+
+namespace content {
+
+// TODO(posciak): this class should be an implementation of
+// content::GpuVideoDecodeAcceleratorFactory, however that can only be achieved
+// once this is moved out of content/common, see crbug.com/597150 and related.
+class CONTENT_EXPORT GpuVideoDecodeAcceleratorFactoryImpl {
+public:
+ ~GpuVideoDecodeAcceleratorFactoryImpl();
+
+ // Return current GLContext.
+ using GetGLContextCallback = base::Callback<gfx::GLContext*(void)>;
+
+ // Make the applicable GL context current. To be called by VDAs before
+ // executing any GL calls. Return true on success, false otherwise.
+ using MakeGLContextCurrentCallback = base::Callback<bool(void)>;
+
+ // Bind |image| to |client_texture_id| given |texture_target|. If
+ // |can_bind_to_sampler| is true, then the image may be used as a sampler
+ // directly, otherwise a copy to a staging buffer is required.
+ // Return true on success, false otherwise.
+ using BindGLImageCallback =
+ base::Callback<bool(uint32_t client_texture_id,
+ uint32_t texture_target,
+ const scoped_refptr<gl::GLImage>& image,
+ bool can_bind_to_sampler)>;
+
+ // Return a WeakPtr to a GLES2Decoder, if one is available.
+ using GetGLES2DecoderCallback =
+ base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>;
+
+ static scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> Create(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb);
+
+ static scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl>
+ CreateWithGLES2Decoder(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb);
+
+ static gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilities(
+ const gpu::GpuPreferences& gpu_preferences);
+
+ scoped_ptr<media::VideoDecodeAccelerator> CreateVDA(
+ media::VideoDecodeAccelerator::Client* client,
+ const media::VideoDecodeAccelerator::Config& config,
+ const gpu::GpuPreferences& gpu_preferences);
+
+ private:
+ GpuVideoDecodeAcceleratorFactoryImpl(
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb,
+ const GetGLES2DecoderCallback& get_gles2_decoder_cb);
+
+#if defined(OS_WIN)
+ scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+#endif
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
+ scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+ scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SVDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+#endif
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
+ scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+#endif
+#if defined(OS_MACOSX)
+ scoped_ptr<media::VideoDecodeAccelerator> CreateVTVDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+#endif
+#if defined(OS_ANDROID)
+ scoped_ptr<media::VideoDecodeAccelerator> CreateAndroidVDA(
+ const gpu::GpuPreferences& gpu_preferences) const;
+#endif
+
+ const GetGLContextCallback get_gl_context_cb_;
+ const MakeGLContextCurrentCallback make_context_current_cb_;
+ const BindGLImageCallback bind_image_cb_;
+ const GetGLES2DecoderCallback get_gles2_decoder_cb_;
+
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(GpuVideoDecodeAcceleratorFactoryImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_
diff --git a/chromium/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h
new file mode 100644
index 00000000000..1717f592603
--- /dev/null
+++ b/chromium/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h
@@ -0,0 +1,59 @@
+// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_
+#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+
+namespace gfx {
+class GLContext;
+}
+
+namespace gl {
+class GLImage;
+}
+
+namespace gpu {
+namespace gles2 {
+class GLES2Decoder;
+}
+}
+
+namespace content {
+
+// Helpers/defines for specific VideoDecodeAccelerator implementations in GPU
+// process. Which callbacks are required depends on the implementation.
+//
+// Note that these callbacks may be called more than once, and so must own/share
+// ownership of any objects bound to them.
+//
+// Unless specified otherwise, these callbacks must be executed on the GPU Child
+// thread (i.e. the thread which the VDAs are initialized on).
+
+// Return current GLContext.
+using GetGLContextCallback = base::Callback<gfx::GLContext*(void)>;
+
+// Make the applicable GL context current. To be called by VDAs before
+// executing any GL calls. Return true on success, false otherwise.
+using MakeGLContextCurrentCallback = base::Callback<bool(void)>;
+
+// Bind |image| to |client_texture_id| given |texture_target|. If
+// |can_bind_to_sampler| is true, then the image may be used as a sampler
+// directly, otherwise a copy to a staging buffer is required.
+// Return true on success, false otherwise.
+using BindGLImageCallback =
+ base::Callback<bool(uint32_t client_texture_id,
+ uint32_t texture_target,
+ const scoped_refptr<gl::GLImage>& image,
+ bool can_bind_to_sampler)>;
+
+// Return a WeakPtr to a GLES2Decoder, if one is available.
+using GetGLES2DecoderCallback =
+ base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>;
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_
diff --git a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc
index 7dd9a082b1d..7b1457e88f1 100644
--- a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc
+++ b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.cc
@@ -11,15 +11,15 @@
#include "base/numerics/safe_math.h"
#include "base/sys_info.h"
#include "build/build_config.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/media/gpu_video_accelerator_util.h"
-#include "content/public/common/content_switches.h"
+#include "gpu/ipc/client/gpu_memory_buffer_impl.h"
+#include "gpu/ipc/service/gpu_channel.h"
+#include "gpu/ipc/service/gpu_channel_manager.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/limits.h"
#include "media/base/video_frame.h"
+#include "media/gpu/ipc/common/gpu_video_accelerator_util.h"
+#include "media/gpu/ipc/common/media_messages.h"
#if defined(OS_CHROMEOS)
#if defined(USE_V4L2_CODEC)
@@ -30,20 +30,14 @@
#endif
#elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
#include "content/common/gpu/media/android_video_encode_accelerator.h"
+#elif defined(OS_MACOSX)
+#include "content/common/gpu/media/vt_video_encode_accelerator_mac.h"
#endif
namespace content {
-namespace {
-
-// Allocation and destruction of buffer are done on the Browser process, so we
-// don't need to handle synchronization here.
-void DestroyGpuMemoryBuffer(const gpu::SyncToken& sync_token) {}
-
-} // namespace
-
static bool MakeDecoderContextCurrent(
- const base::WeakPtr<GpuCommandBufferStub> stub) {
+ const base::WeakPtr<gpu::GpuCommandBufferStub> stub) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
return false;
@@ -57,8 +51,9 @@ static bool MakeDecoderContextCurrent(
return true;
}
-GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(int32_t host_route_id,
- GpuCommandBufferStub* stub)
+GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(
+ int32_t host_route_id,
+ gpu::GpuCommandBufferStub* stub)
: host_route_id_(host_route_id),
stub_(stub),
input_format_(media::PIXEL_FORMAT_UNKNOWN),
@@ -75,12 +70,11 @@ GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
DCHECK(!encoder_);
}
-void GpuVideoEncodeAccelerator::Initialize(
+bool GpuVideoEncodeAccelerator::Initialize(
media::VideoPixelFormat input_format,
const gfx::Size& input_visible_size,
media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- IPC::Message* init_done_msg) {
+ uint32_t initial_bitrate) {
DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): "
"input_format=" << input_format
<< ", input_visible_size=" << input_visible_size.ToString()
@@ -88,11 +82,10 @@ void GpuVideoEncodeAccelerator::Initialize(
<< ", initial_bitrate=" << initial_bitrate;
DCHECK(!encoder_);
- if (!stub_->channel()->AddRoute(host_route_id_, this)) {
+ if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) {
DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
"failed to add route";
- SendCreateEncoderReply(init_done_msg, false);
- return;
+ return false;
}
if (input_visible_size.width() > media::limits::kMaxDimension ||
@@ -101,12 +94,14 @@ void GpuVideoEncodeAccelerator::Initialize(
DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
"input_visible_size " << input_visible_size.ToString()
<< " too large";
- SendCreateEncoderReply(init_done_msg, false);
- return;
+ return false;
}
- std::vector<GpuVideoEncodeAccelerator::CreateVEAFp>
- create_vea_fps = CreateVEAFps();
+ const gpu::GpuPreferences& gpu_preferences =
+ stub_->channel()->gpu_channel_manager()->gpu_preferences();
+
+ std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps =
+ CreateVEAFps(gpu_preferences);
// Try all possible encoders and use the first successful encoder.
for (size_t i = 0; i < create_vea_fps.size(); ++i) {
encoder_ = (*create_vea_fps[i])();
@@ -117,14 +112,13 @@ void GpuVideoEncodeAccelerator::Initialize(
this)) {
input_format_ = input_format;
input_visible_size_ = input_visible_size;
- SendCreateEncoderReply(init_done_msg, true);
- return;
+ return true;
}
}
encoder_.reset();
DLOG(ERROR)
<< "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed";
- SendCreateEncoderReply(init_done_msg, false);
+ return false;
}
bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
@@ -176,10 +170,11 @@ void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
// static
gpu::VideoEncodeAcceleratorSupportedProfiles
-GpuVideoEncodeAccelerator::GetSupportedProfiles() {
+GpuVideoEncodeAccelerator::GetSupportedProfiles(
+ const gpu::GpuPreferences& gpu_preferences) {
media::VideoEncodeAccelerator::SupportedProfiles profiles;
- std::vector<GpuVideoEncodeAccelerator::CreateVEAFp>
- create_vea_fps = CreateVEAFps();
+ std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps =
+ CreateVEAFps(gpu_preferences);
for (size_t i = 0; i < create_vea_fps.size(); ++i) {
scoped_ptr<media::VideoEncodeAccelerator>
@@ -188,55 +183,73 @@ GpuVideoEncodeAccelerator::GetSupportedProfiles() {
continue;
media::VideoEncodeAccelerator::SupportedProfiles vea_profiles =
encoder->GetSupportedProfiles();
- GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(
- vea_profiles, &profiles);
+ media::GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles,
+ &profiles);
}
- return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
+ return media::GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(
+ profiles);
}
// static
std::vector<GpuVideoEncodeAccelerator::CreateVEAFp>
-GpuVideoEncodeAccelerator::CreateVEAFps() {
+GpuVideoEncodeAccelerator::CreateVEAFps(
+ const gpu::GpuPreferences& gpu_preferences) {
std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps;
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateV4L2VEA);
- create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateVaapiVEA);
- create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateAndroidVEA);
+#endif
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
+ if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
+ create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateVaapiVEA);
+#endif
+#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
+ if (!gpu_preferences.disable_web_rtc_hw_encoding)
+ create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateAndroidVEA);
+#endif
+#if defined(OS_MACOSX)
+ create_vea_fps.push_back(&GpuVideoEncodeAccelerator::CreateVTVEA);
+#endif
return create_vea_fps;
}
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateV4L2VEA() {
scoped_ptr<media::VideoEncodeAccelerator> encoder;
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder);
if (device)
encoder.reset(new V4L2VideoEncodeAccelerator(device));
-#endif
return encoder;
}
+#endif
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateVaapiVEA() {
- scoped_ptr<media::VideoEncodeAccelerator> encoder;
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- if (!cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode))
- encoder.reset(new VaapiVideoEncodeAccelerator());
-#endif
- return encoder;
+ return make_scoped_ptr<media::VideoEncodeAccelerator>(
+ new VaapiVideoEncodeAccelerator());
}
+#endif
+#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
// static
scoped_ptr<media::VideoEncodeAccelerator>
GpuVideoEncodeAccelerator::CreateAndroidVEA() {
- scoped_ptr<media::VideoEncodeAccelerator> encoder;
-#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
- encoder.reset(new AndroidVideoEncodeAccelerator());
+ return make_scoped_ptr<media::VideoEncodeAccelerator>(
+ new AndroidVideoEncodeAccelerator());
+}
#endif
- return encoder;
+
+#if defined(OS_MACOSX)
+// static
+scoped_ptr<media::VideoEncodeAccelerator>
+GpuVideoEncodeAccelerator::CreateVTVEA() {
+ return make_scoped_ptr<media::VideoEncodeAccelerator>(
+ new VTVideoEncodeAccelerator());
}
+#endif
void GpuVideoEncodeAccelerator::OnEncode(
const AcceleratedVideoEncoderMsg_Encode_Params& params) {
@@ -315,79 +328,8 @@ void GpuVideoEncodeAccelerator::OnEncode2(
<< params.frame_id << ", size=" << params.size.ToString()
<< ", force_keyframe=" << params.force_keyframe << ", handle type="
<< params.gpu_memory_buffer_handles[0].type;
- DCHECK_EQ(media::PIXEL_FORMAT_I420, input_format_);
- DCHECK_EQ(media::VideoFrame::NumPlanes(input_format_),
- params.gpu_memory_buffer_handles.size());
-
- bool map_result = true;
- uint8_t* data[media::VideoFrame::kMaxPlanes];
- int32_t strides[media::VideoFrame::kMaxPlanes];
- ScopedVector<gfx::GpuMemoryBuffer> buffers;
- const auto& handles = params.gpu_memory_buffer_handles;
- for (size_t i = 0; i < handles.size(); ++i) {
- const size_t width =
- media::VideoFrame::Columns(i, input_format_, params.size.width());
- const size_t height =
- media::VideoFrame::Rows(i, input_format_, params.size.height());
- scoped_ptr<gfx::GpuMemoryBuffer> buffer =
- GpuMemoryBufferImpl::CreateFromHandle(
- handles[i], gfx::Size(width, height), gfx::BufferFormat::R_8,
- gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
- media::BindToCurrentLoop(base::Bind(&DestroyGpuMemoryBuffer)));
-
- // TODO(emircan): Refactor such that each frame is mapped once.
- // See http://crbug/536938.
- if (!buffer.get() || !buffer->Map()) {
- map_result = false;
- continue;
- }
-
- data[i] = reinterpret_cast<uint8_t*>(buffer->memory(0));
- strides[i] = buffer->stride(0);
- buffers.push_back(buffer.release());
- }
-
- if (!map_result) {
- DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): "
- << "failed to map buffers";
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
-
- if (!encoder_)
- return;
-
- if (params.frame_id < 0) {
- DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): invalid frame_id="
- << params.frame_id;
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
-
- scoped_refptr<media::VideoFrame> frame =
- media::VideoFrame::WrapExternalYuvData(
- input_format_,
- input_coded_size_,
- gfx::Rect(input_visible_size_),
- input_visible_size_,
- strides[media::VideoFrame::kYPlane],
- strides[media::VideoFrame::kUPlane],
- strides[media::VideoFrame::kVPlane],
- data[media::VideoFrame::kYPlane],
- data[media::VideoFrame::kUPlane],
- data[media::VideoFrame::kVPlane],
- params.timestamp);
- if (!frame.get()) {
- DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode2(): "
- << "could not create a frame";
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
- frame->AddDestructionObserver(media::BindToCurrentLoop(
- base::Bind(&GpuVideoEncodeAccelerator::EncodeFrameFinished2,
- weak_this_factory_.GetWeakPtr(), params.frame_id,
- base::Passed(&buffers))));
- encoder_->Encode(frame, params.force_keyframe);
+ // Encoding GpuMemoryBuffer backed frames is not supported.
+ NOTREACHED();
}
void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(
@@ -439,25 +381,8 @@ void GpuVideoEncodeAccelerator::EncodeFrameFinished(
// Just let |shm| fall out of scope.
}
-void GpuVideoEncodeAccelerator::EncodeFrameFinished2(
- int32_t frame_id,
- ScopedVector<gfx::GpuMemoryBuffer> buffers) {
- // TODO(emircan): Consider calling Unmap() in dtor.
- for (const auto& buffer : buffers)
- buffer->Unmap();
- Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
- frame_id));
- // Just let |buffers| fall out of scope.
-}
-
void GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
stub_->channel()->Send(message);
}
-void GpuVideoEncodeAccelerator::SendCreateEncoderReply(IPC::Message* message,
- bool succeeded) {
- GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(message, succeeded);
- Send(message);
-}
-
} // namespace content
diff --git a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h
index ecc14f28e99..2c2db293db3 100644
--- a/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h
+++ b/chromium/content/common/gpu/media/gpu_video_encode_accelerator.h
@@ -13,8 +13,8 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/ipc/service/gpu_command_buffer_stub.h"
#include "ipc/ipc_listener.h"
#include "media/video/video_encode_accelerator.h"
#include "ui/gfx/geometry/size.h"
@@ -26,6 +26,10 @@ namespace base {
class SharedMemory;
} // namespace base
+namespace gpu {
+struct GpuPreferences;
+} // namespace gpu
+
namespace content {
// This class encapsulates the GPU process view of a VideoEncodeAccelerator,
@@ -34,18 +38,18 @@ namespace content {
class GpuVideoEncodeAccelerator
: public IPC::Listener,
public media::VideoEncodeAccelerator::Client,
- public GpuCommandBufferStub::DestructionObserver {
+ public gpu::GpuCommandBufferStub::DestructionObserver {
public:
- GpuVideoEncodeAccelerator(int32_t host_route_id, GpuCommandBufferStub* stub);
+ GpuVideoEncodeAccelerator(int32_t host_route_id,
+ gpu::GpuCommandBufferStub* stub);
~GpuVideoEncodeAccelerator() override;
// Initialize this accelerator with the given parameters and send
// |init_done_msg| when complete.
- void Initialize(media::VideoPixelFormat input_format,
+ bool Initialize(media::VideoPixelFormat input_format,
const gfx::Size& input_visible_size,
media::VideoCodecProfile output_profile,
- uint32_t initial_bitrate,
- IPC::Message* init_done_msg);
+ uint32_t initial_bitrate);
// IPC::Listener implementation
bool OnMessageReceived(const IPC::Message& message) override;
@@ -59,23 +63,34 @@ class GpuVideoEncodeAccelerator
bool key_frame) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
- // GpuCommandBufferStub::DestructionObserver implementation.
+ // gpu::GpuCommandBufferStub::DestructionObserver implementation.
void OnWillDestroyStub() override;
// Static query for supported profiles. This query calls the appropriate
// platform-specific version. The returned supported profiles vector will
// not contain duplicates.
- static gpu::VideoEncodeAcceleratorSupportedProfiles GetSupportedProfiles();
+ static gpu::VideoEncodeAcceleratorSupportedProfiles GetSupportedProfiles(
+ const gpu::GpuPreferences& gpu_preferences);
private:
typedef scoped_ptr<media::VideoEncodeAccelerator>(*CreateVEAFp)();
// Return a set of VEA Create function pointers applicable to the current
// platform.
- static std::vector<CreateVEAFp> CreateVEAFps();
+ static std::vector<CreateVEAFp> CreateVEAFps(
+ const gpu::GpuPreferences& gpu_preferences);
+#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
static scoped_ptr<media::VideoEncodeAccelerator> CreateV4L2VEA();
+#endif
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
static scoped_ptr<media::VideoEncodeAccelerator> CreateVaapiVEA();
+#endif
+#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
static scoped_ptr<media::VideoEncodeAccelerator> CreateAndroidVEA();
+#endif
+#if defined(OS_MACOSX)
+ static scoped_ptr<media::VideoEncodeAccelerator> CreateVTVEA();
+#endif
// IPC handlers, proxying media::VideoEncodeAccelerator for the renderer
// process.
@@ -90,19 +105,15 @@ class GpuVideoEncodeAccelerator
void EncodeFrameFinished(int32_t frame_id,
scoped_ptr<base::SharedMemory> shm);
- void EncodeFrameFinished2(int32_t frame_id,
- ScopedVector<gfx::GpuMemoryBuffer> buffers);
void Send(IPC::Message* message);
- // Helper for replying to the creation request.
- void SendCreateEncoderReply(IPC::Message* message, bool succeeded);
// Route ID to communicate with the host.
const uint32_t host_route_id_;
- // Unowned pointer to the underlying GpuCommandBufferStub. |this| is
+ // Unowned pointer to the underlying gpu::GpuCommandBufferStub. |this| is
// registered as a DestuctionObserver of |stub_| and will self-delete when
// |stub_| is destroyed.
- GpuCommandBufferStub* const stub_;
+ gpu::GpuCommandBufferStub* const stub_;
// Owned pointer to the underlying VideoEncodeAccelerator.
scoped_ptr<media::VideoEncodeAccelerator> encoder_;
diff --git a/chromium/content/common/gpu/media/media_channel.cc b/chromium/content/common/gpu/media/media_channel.cc
new file mode 100644
index 00000000000..7baeba075e4
--- /dev/null
+++ b/chromium/content/common/gpu/media/media_channel.cc
@@ -0,0 +1,145 @@
+// Copyright 2016 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 "content/common/gpu/media/media_channel.h"
+
+#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
+#include "content/common/gpu/media/gpu_video_encode_accelerator.h"
+#include "gpu/ipc/service/gpu_channel.h"
+#include "media/gpu/ipc/common/media_messages.h"
+
+namespace content {
+
+namespace {
+
+void SendCreateJpegDecoderResult(
+ scoped_ptr<IPC::Message> reply_message,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ base::WeakPtr<gpu::GpuChannel> channel,
+ scoped_refptr<gpu::GpuChannelMessageFilter> filter,
+ bool result) {
+ GpuChannelMsg_CreateJpegDecoder::WriteReplyParams(reply_message.get(),
+ result);
+ if (io_task_runner->BelongsToCurrentThread()) {
+ filter->Send(reply_message.release());
+ } else if (channel) {
+ channel->Send(reply_message.release());
+ }
+}
+
+} // namespace
+
+class MediaChannelDispatchHelper {
+ public:
+ MediaChannelDispatchHelper(MediaChannel* channel, int32_t routing_id)
+ : channel_(channel), routing_id_(routing_id) {}
+
+ bool Send(IPC::Message* msg) { return channel_->Send(msg); }
+
+ void OnCreateVideoDecoder(const media::VideoDecodeAccelerator::Config& config,
+ int32_t decoder_route_id,
+ IPC::Message* reply_message) {
+ channel_->OnCreateVideoDecoder(routing_id_, config, decoder_route_id,
+ reply_message);
+ }
+
+ void OnCreateVideoEncoder(const media::CreateVideoEncoderParams& params,
+ IPC::Message* reply_message) {
+ channel_->OnCreateVideoEncoder(routing_id_, params, reply_message);
+ }
+
+ private:
+ MediaChannel* const channel_;
+ const int32_t routing_id_;
+ DISALLOW_COPY_AND_ASSIGN(MediaChannelDispatchHelper);
+};
+
+MediaChannel::MediaChannel(gpu::GpuChannel* channel) : channel_(channel) {}
+
+MediaChannel::~MediaChannel() {}
+
+bool MediaChannel::Send(IPC::Message* msg) {
+ return channel_->Send(msg);
+}
+
+bool MediaChannel::OnMessageReceived(const IPC::Message& message) {
+ MediaChannelDispatchHelper helper(this, message.routing_id());
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MediaChannel, message)
+ IPC_MESSAGE_FORWARD_DELAY_REPLY(
+ GpuCommandBufferMsg_CreateVideoDecoder, &helper,
+ MediaChannelDispatchHelper::OnCreateVideoDecoder)
+ IPC_MESSAGE_FORWARD_DELAY_REPLY(
+ GpuCommandBufferMsg_CreateVideoEncoder, &helper,
+ MediaChannelDispatchHelper::OnCreateVideoEncoder)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateJpegDecoder,
+ OnCreateJpegDecoder)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void MediaChannel::OnCreateJpegDecoder(int32_t route_id,
+ IPC::Message* reply_msg) {
+ scoped_ptr<IPC::Message> msg(reply_msg);
+ if (!jpeg_decoder_) {
+ jpeg_decoder_.reset(
+ new GpuJpegDecodeAccelerator(channel_, channel_->io_task_runner()));
+ }
+ jpeg_decoder_->AddClient(
+ route_id, base::Bind(&SendCreateJpegDecoderResult, base::Passed(&msg),
+ channel_->io_task_runner(), channel_->AsWeakPtr(),
+ make_scoped_refptr(channel_->filter())));
+}
+
+void MediaChannel::OnCreateVideoDecoder(
+ int32_t command_buffer_route_id,
+ const media::VideoDecodeAccelerator::Config& config,
+ int32_t decoder_route_id,
+ IPC::Message* reply_message) {
+ TRACE_EVENT0("gpu", "MediaChannel::OnCreateVideoDecoder");
+ gpu::GpuCommandBufferStub* stub =
+ channel_->LookupCommandBuffer(command_buffer_route_id);
+ if (!stub) {
+ reply_message->set_reply_error();
+ Send(reply_message);
+ return;
+ }
+ GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator(
+ decoder_route_id, stub, stub->channel()->io_task_runner());
+ bool succeeded = decoder->Initialize(config);
+ GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(reply_message,
+ succeeded);
+ Send(reply_message);
+
+ // decoder is registered as a DestructionObserver of this stub and will
+ // self-delete during destruction of this stub.
+}
+
+void MediaChannel::OnCreateVideoEncoder(
+ int32_t command_buffer_route_id,
+ const media::CreateVideoEncoderParams& params,
+ IPC::Message* reply_message) {
+ TRACE_EVENT0("gpu", "MediaChannel::OnCreateVideoEncoder");
+ gpu::GpuCommandBufferStub* stub =
+ channel_->LookupCommandBuffer(command_buffer_route_id);
+ if (!stub) {
+ reply_message->set_reply_error();
+ Send(reply_message);
+ return;
+ }
+ GpuVideoEncodeAccelerator* encoder =
+ new GpuVideoEncodeAccelerator(params.encoder_route_id, stub);
+ bool succeeded =
+ encoder->Initialize(params.input_format, params.input_visible_size,
+ params.output_profile, params.initial_bitrate);
+ GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(reply_message,
+ succeeded);
+ Send(reply_message);
+
+ // encoder is registered as a DestructionObserver of this stub and will
+ // self-delete during destruction of this stub.
+}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/media/media_channel.h b/chromium/content/common/gpu/media/media_channel.h
new file mode 100644
index 00000000000..7cfe0378587
--- /dev/null
+++ b/chromium/content/common/gpu/media/media_channel.h
@@ -0,0 +1,57 @@
+// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_MEDIA_CHANNEL_H_
+#define CONTENT_COMMON_GPU_MEDIA_MEDIA_CHANNEL_H_
+
+#include "content/common/gpu/media/gpu_jpeg_decode_accelerator.h"
+#include "ipc/ipc_listener.h"
+#include "ipc/ipc_sender.h"
+#include "media/video/video_decode_accelerator.h"
+
+namespace media {
+struct CreateVideoEncoderParams;
+}
+
+namespace gpu {
+class GpuChannel;
+class GpuCommandBufferStub;
+}
+
+namespace content {
+
+class MediaChannelDispatchHelper;
+
+class MediaChannel : public IPC::Listener, public IPC::Sender {
+ public:
+ explicit MediaChannel(gpu::GpuChannel* channel);
+ ~MediaChannel() override;
+
+ // IPC::Sender implementation:
+ bool Send(IPC::Message* msg) override;
+
+ private:
+ friend class MediaChannelDispatchHelper;
+
+ // IPC::Listener implementation:
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ // Message handlers.
+ void OnCreateJpegDecoder(int32_t route_id, IPC::Message* reply_msg);
+ void OnCreateVideoDecoder(int32_t command_buffer_route_id,
+ const media::VideoDecodeAccelerator::Config& config,
+ int32_t route_id,
+ IPC::Message* reply_message);
+ void OnCreateVideoEncoder(int32_t command_buffer_route_id,
+ const media::CreateVideoEncoderParams& params,
+ IPC::Message* reply_message);
+
+ gpu::GpuChannel* const channel_;
+ scoped_ptr<GpuJpegDecodeAccelerator> jpeg_decoder_;
+ DISALLOW_COPY_AND_ASSIGN(MediaChannel);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_MEDIA_CHANNEL_H_
diff --git a/chromium/content/common/gpu/media/media_service.cc b/chromium/content/common/gpu/media/media_service.cc
new file mode 100644
index 00000000000..89ec8b1fe50
--- /dev/null
+++ b/chromium/content/common/gpu/media/media_service.cc
@@ -0,0 +1,40 @@
+// Copyright 2016 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 "content/common/gpu/media/media_service.h"
+
+#include <utility>
+
+#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
+#include "content/common/gpu/media/gpu_video_encode_accelerator.h"
+#include "content/common/gpu/media/media_channel.h"
+#include "gpu/ipc/service/gpu_channel.h"
+#include "gpu/ipc/service/gpu_channel_manager.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/param_traits_macros.h"
+
+namespace content {
+
+MediaService::MediaService(gpu::GpuChannelManager* channel_manager)
+ : channel_manager_(channel_manager) {}
+
+MediaService::~MediaService() {}
+
+void MediaService::AddChannel(int32_t client_id) {
+ gpu::GpuChannel* gpu_channel = channel_manager_->LookupChannel(client_id);
+ DCHECK(gpu_channel);
+ scoped_ptr<MediaChannel> media_channel(new MediaChannel(gpu_channel));
+ gpu_channel->SetUnhandledMessageListener(media_channel.get());
+ media_channels_.set(client_id, std::move(media_channel));
+}
+
+void MediaService::RemoveChannel(int32_t client_id) {
+ media_channels_.erase(client_id);
+}
+
+void MediaService::DestroyAllChannels() {
+ media_channels_.clear();
+}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/media/media_service.h b/chromium/content/common/gpu/media/media_service.h
new file mode 100644
index 00000000000..15dca82260a
--- /dev/null
+++ b/chromium/content/common/gpu/media/media_service.h
@@ -0,0 +1,42 @@
+// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_MEDIA_SERVICE_H_
+#define CONTENT_COMMON_GPU_MEDIA_MEDIA_SERVICE_H_
+
+#include <stdint.h>
+
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
+#include "ipc/ipc_listener.h"
+#include "ipc/ipc_sender.h"
+#include "media/video/video_decode_accelerator.h"
+
+namespace gpu {
+class GpuChannel;
+class GpuChannelManager;
+}
+
+namespace content {
+
+class MediaChannel;
+
+class MediaService {
+ public:
+ MediaService(gpu::GpuChannelManager* channel_manager);
+ ~MediaService();
+
+ void AddChannel(int32_t client_id);
+ void RemoveChannel(int32_t client_id);
+ void DestroyAllChannels();
+
+ private:
+ gpu::GpuChannelManager* const channel_manager_;
+ base::ScopedPtrHashMap<int32_t, scoped_ptr<MediaChannel>> media_channels_;
+ DISALLOW_COPY_AND_ASSIGN(MediaService);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_MEDIA_SERVICE_H_
diff --git a/chromium/content/common/gpu/media/rendering_helper.cc b/chromium/content/common/gpu/media/rendering_helper.cc
index 85bfe0a840d..2a19428b2d0 100644
--- a/chromium/content/common/gpu/media/rendering_helper.cc
+++ b/chromium/content/common/gpu/media/rendering_helper.cc
@@ -160,6 +160,9 @@ RenderingHelperParams::RenderingHelperParams()
: rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) {
}
+RenderingHelperParams::RenderingHelperParams(
+ const RenderingHelperParams& other) = default;
+
RenderingHelperParams::~RenderingHelperParams() {}
VideoFrameTexture::VideoFrameTexture(uint32_t texture_target,
@@ -179,6 +182,9 @@ RenderingHelper::RenderedVideo::RenderedVideo()
: is_flushing(false), frames_to_drop(0) {
}
+RenderingHelper::RenderedVideo::RenderedVideo(const RenderedVideo& other) =
+ default;
+
RenderingHelper::RenderedVideo::~RenderedVideo() {
}
@@ -665,12 +671,8 @@ void RenderingHelper::DeleteTexture(uint32_t texture_id) {
CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
}
-scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() {
- return gl_context_;
-}
-
-void* RenderingHelper::GetGLContextHandle() {
- return gl_context_->GetHandle();
+gfx::GLContext* RenderingHelper::GetGLContext() {
+ return gl_context_.get();
}
void* RenderingHelper::GetGLDisplay() {
diff --git a/chromium/content/common/gpu/media/rendering_helper.h b/chromium/content/common/gpu/media/rendering_helper.h
index 8a6c28bd3f7..250d382ac61 100644
--- a/chromium/content/common/gpu/media/rendering_helper.h
+++ b/chromium/content/common/gpu/media/rendering_helper.h
@@ -54,6 +54,7 @@ class VideoFrameTexture : public base::RefCounted<VideoFrameTexture> {
struct RenderingHelperParams {
RenderingHelperParams();
+ RenderingHelperParams(const RenderingHelperParams& other);
~RenderingHelperParams();
// The rendering FPS.
@@ -135,10 +136,7 @@ class RenderingHelper {
void* GetGLDisplay();
// Get the GL context.
- scoped_refptr<gfx::GLContext> GetGLContext();
-
- // Get the platform specific handle to the OpenGL context.
- void* GetGLContextHandle();
+ gfx::GLContext* GetGLContext();
// Get rendered thumbnails as RGB.
// Sets alpha_solid to true if the alpha channel is entirely 0xff.
@@ -165,6 +163,7 @@ class RenderingHelper {
std::queue<scoped_refptr<VideoFrameTexture> > pending_frames;
RenderedVideo();
+ RenderedVideo(const RenderedVideo& other);
~RenderedVideo();
};
diff --git a/chromium/content/common/gpu/media/shared_memory_region.cc b/chromium/content/common/gpu/media/shared_memory_region.cc
new file mode 100644
index 00000000000..4ee6a242578
--- /dev/null
+++ b/chromium/content/common/gpu/media/shared_memory_region.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2015 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/sys_info.h"
+#include "content/common/gpu/media/shared_memory_region.h"
+
+namespace content {
+
+SharedMemoryRegion::SharedMemoryRegion(const base::SharedMemoryHandle& handle,
+ off_t offset,
+ size_t size,
+ bool read_only)
+ : shm_(handle, read_only),
+ offset_(offset),
+ size_(size),
+ alignment_size_(offset % base::SysInfo::VMAllocationGranularity()) {
+ DCHECK_GE(offset_, 0) << "Invalid offset: " << offset_;
+}
+
+SharedMemoryRegion::SharedMemoryRegion(
+ const media::BitstreamBuffer& bitstream_buffer,
+ bool read_only)
+ : SharedMemoryRegion(bitstream_buffer.handle(),
+ bitstream_buffer.offset(),
+ bitstream_buffer.size(),
+ read_only) {}
+
+bool SharedMemoryRegion::Map() {
+ if (offset_ < 0) {
+ DVLOG(1) << "Invalid offset: " << offset_;
+ return false;
+ }
+ return shm_.MapAt(offset_ - alignment_size_, size_ + alignment_size_);
+}
+
+void* SharedMemoryRegion::memory() {
+ int8_t* addr = reinterpret_cast<int8_t*>(shm_.memory());
+ return addr ? addr + alignment_size_ : nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/media/shared_memory_region.h b/chromium/content/common/gpu/media/shared_memory_region.h
new file mode 100644
index 00000000000..f7c5db29982
--- /dev/null
+++ b/chromium/content/common/gpu/media/shared_memory_region.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2015 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 CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_
+#define CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_
+
+#include "base/memory/shared_memory.h"
+#include "media/base/bitstream_buffer.h"
+
+namespace content {
+
+// Helper class to access a region of a SharedMemory. Different from
+// SharedMemory, in which the |offset| of function MapAt() must be aligned to
+// the value of |SysInfo::VMAllocationGranularity()|, the |offset| of a
+// SharedMemoryRegion needs not to be aligned, this class hides the details
+// and returns the mapped address of the given offset.
+class SharedMemoryRegion {
+ public:
+ // Creates a SharedMemoryRegion.
+ // The mapped memory region begins at |offset| bytes from the start of the
+ // shared memory and the length is |size|. It will take the ownership of
+ // the |handle| and release the resource when being destroyed. Different
+ // from SharedMemory, the |offset| needs not to be aligned to the value of
+ // |SysInfo::VMAllocationGranularity()|.
+ SharedMemoryRegion(const base::SharedMemoryHandle& handle,
+ off_t offset,
+ size_t size,
+ bool read_only);
+
+ // Creates a SharedMemoryRegion from the given |bistream_buffer|.
+ SharedMemoryRegion(const media::BitstreamBuffer& bitstream_buffer,
+ bool read_only);
+
+ // Maps the shared memory into the caller's address space.
+ // Return true on success, false otherwise.
+ bool Map();
+
+ // Gets a pointer to the mapped region if it has been mapped via Map().
+ // Returns |nullptr| if it is not mapped. The returned pointer points
+ // to the memory at the offset previously passed to the constructor.
+ void* memory();
+
+ size_t size() const { return size_; }
+
+ private:
+ base::SharedMemory shm_;
+ off_t offset_;
+ size_t size_;
+ size_t alignment_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemoryRegion);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_SHARED_MEMORY_REGION_H_
diff --git a/chromium/content/common/gpu/media/v4l2_image_processor.cc b/chromium/content/common/gpu/media/v4l2_image_processor.cc
index f0cf3977774..340a1484335 100644
--- a/chromium/content/common/gpu/media/v4l2_image_processor.cc
+++ b/chromium/content/common/gpu/media/v4l2_image_processor.cc
@@ -468,24 +468,22 @@ void V4L2ImageProcessor::Enqueue() {
}
}
- // TODO(posciak): Fix this to be non-Exynos specific.
- // Exynos GSC is liable to race conditions if more than one output buffer is
- // simultaneously enqueued, so enqueue just one.
- if (output_buffer_queued_count_ == 0 && !free_output_buffers_.empty()) {
- const int old_outputs_queued = output_buffer_queued_count_;
+ const int old_outputs_queued = output_buffer_queued_count_;
+ while (!free_output_buffers_.empty()) {
if (!EnqueueOutputRecord())
return;
- if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
- // We just started up a previously empty queue.
- // Queue state changed; signal interrupt.
- if (!device_->SetDevicePollInterrupt())
- return;
- // Start VIDIOC_STREAMON if we haven't yet.
- if (!output_streamon_) {
- __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
- output_streamon_ = true;
- }
+ }
+
+ if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
+ // We just started up a previously empty queue.
+ // Queue state changed; signal interrupt.
+ if (!device_->SetDevicePollInterrupt())
+ return;
+ // Start VIDIOC_STREAMON if we haven't yet.
+ if (!output_streamon_) {
+ __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+ output_streamon_ = true;
}
}
DCHECK_LE(output_buffer_queued_count_, 1);
diff --git a/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc b/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc
index 06091a36b4d..0121eadbc09 100644
--- a/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.cc
@@ -112,10 +112,11 @@ V4L2JpegDecodeAccelerator::BufferRecord::~BufferRecord() {
}
V4L2JpegDecodeAccelerator::JobRecord::JobRecord(
- media::BitstreamBuffer bitstream_buffer,
+ const media::BitstreamBuffer& bitstream_buffer,
scoped_refptr<media::VideoFrame> video_frame)
- : bitstream_buffer(bitstream_buffer), out_frame(video_frame) {
-}
+ : bitstream_buffer_id(bitstream_buffer.id()),
+ shm(bitstream_buffer, true),
+ out_frame(video_frame) {}
V4L2JpegDecodeAccelerator::JobRecord::~JobRecord() {
}
@@ -233,6 +234,14 @@ void V4L2JpegDecodeAccelerator::Decode(
<< ", size=" << bitstream_buffer.size();
DCHECK(io_task_runner_->BelongsToCurrentThread());
+ if (bitstream_buffer.id() < 0) {
+ LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+ if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
+ base::SharedMemory::CloseHandle(bitstream_buffer.handle());
+ PostNotifyError(bitstream_buffer.id(), INVALID_ARGUMENT);
+ return;
+ }
+
if (video_frame->format() != media::PIXEL_FORMAT_I420) {
PostNotifyError(bitstream_buffer.id(), UNSUPPORTED_JPEG);
return;
@@ -260,11 +269,9 @@ bool V4L2JpegDecodeAccelerator::IsSupported() {
void V4L2JpegDecodeAccelerator::DecodeTask(scoped_ptr<JobRecord> job_record) {
DCHECK(decoder_task_runner_->BelongsToCurrentThread());
- job_record->shm.reset(
- new base::SharedMemory(job_record->bitstream_buffer.handle(), true));
- if (!job_record->shm->Map(job_record->bitstream_buffer.size())) {
+ if (!job_record->shm.Map()) {
PLOG(ERROR) << __func__ << ": could not map bitstream_buffer";
- PostNotifyError(job_record->bitstream_buffer.id(), UNREADABLE_INPUT);
+ PostNotifyError(job_record->bitstream_buffer_id, UNREADABLE_INPUT);
return;
}
input_jobs_.push(make_linked_ptr(job_record.release()));
@@ -288,7 +295,7 @@ bool V4L2JpegDecodeAccelerator::ShouldRecreateInputBuffers() {
linked_ptr<JobRecord> job_record = input_jobs_.front();
// Check input buffer size is enough
return (input_buffer_map_.empty() ||
- (job_record->bitstream_buffer.size() + sizeof(kDefaultDhtSeg)) >
+ (job_record->shm.size() + sizeof(kDefaultDhtSeg)) >
input_buffer_map_.front().length);
}
@@ -333,8 +340,7 @@ bool V4L2JpegDecodeAccelerator::CreateInputBuffers() {
// The input image may miss huffman table. We didn't parse the image before,
// so we create more to avoid the situation of not enough memory.
// Reserve twice size to avoid recreating input buffer frequently.
- size_t reserve_size =
- (job_record->bitstream_buffer.size() + sizeof(kDefaultDhtSeg)) * 2;
+ size_t reserve_size = (job_record->shm.size() + sizeof(kDefaultDhtSeg)) * 2;
struct v4l2_format format;
memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
@@ -711,17 +717,16 @@ void V4L2JpegDecodeAccelerator::Dequeue() {
// V4L2_PIX_FMT_YUV420.
if (!CopyOutputImage(output_buffer_pixelformat_, output_record.address,
output_buffer_coded_size_, job_record->out_frame)) {
- PostNotifyError(job_record->bitstream_buffer.id(), PLATFORM_FAILURE);
+ PostNotifyError(job_record->bitstream_buffer_id, PLATFORM_FAILURE);
return;
}
DVLOG(3) << "Decoding finished, returning bitstream buffer, id="
- << job_record->bitstream_buffer.id();
+ << job_record->bitstream_buffer_id;
child_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&V4L2JpegDecodeAccelerator::VideoFrameReady, weak_ptr_,
- job_record->bitstream_buffer.id()));
+ FROM_HERE, base::Bind(&V4L2JpegDecodeAccelerator::VideoFrameReady,
+ weak_ptr_, job_record->bitstream_buffer_id));
}
}
}
@@ -819,10 +824,9 @@ bool V4L2JpegDecodeAccelerator::EnqueueInputRecord() {
DCHECK(!input_record.at_device);
// It will add default huffman segment if it's missing.
- if (!AddHuffmanTable(job_record->shm->memory(),
- job_record->bitstream_buffer.size(),
+ if (!AddHuffmanTable(job_record->shm.memory(), job_record->shm.size(),
input_record.address, input_record.length)) {
- PostNotifyError(job_record->bitstream_buffer.id(), PARSE_JPEG_FAILED);
+ PostNotifyError(job_record->bitstream_buffer_id, PARSE_JPEG_FAILED);
return false;
}
@@ -836,8 +840,9 @@ bool V4L2JpegDecodeAccelerator::EnqueueInputRecord() {
running_jobs_.push(job_record);
free_input_buffers_.pop_back();
- DVLOG(3) << __func__ << ": enqueued frame id="
- << job_record->bitstream_buffer.id() << " to device.";
+ DVLOG(3) << __func__
+ << ": enqueued frame id=" << job_record->bitstream_buffer_id
+ << " to device.";
return true;
}
diff --git a/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h b/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h
index 435808012ec..bef33b22c10 100644
--- a/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/v4l2_jpeg_decode_accelerator.h
@@ -18,6 +18,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/v4l2_device.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/video_frame.h"
@@ -58,16 +59,16 @@ class CONTENT_EXPORT V4L2JpegDecodeAccelerator
// the time of submission we may not have one available (and don't need one
// to submit input to the device).
struct JobRecord {
- JobRecord(media::BitstreamBuffer bitstream_buffer,
+ JobRecord(const media::BitstreamBuffer& bitstream_buffer,
scoped_refptr<media::VideoFrame> video_frame);
~JobRecord();
- // Input image buffer.
- media::BitstreamBuffer bitstream_buffer;
+ // Input image buffer ID.
+ int32_t bitstream_buffer_id;
+ // Memory mapped from |bitstream_buffer|.
+ SharedMemoryRegion shm;
// Output frame buffer.
scoped_refptr<media::VideoFrame> out_frame;
- // Memory mapped from |bitstream_buffer|.
- scoped_ptr<base::SharedMemory> shm;
};
void EnqueueInput();
diff --git a/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
index 4c3b724daa5..80087232b65 100644
--- a/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
@@ -19,9 +19,11 @@
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
+#include "ui/gl/gl_context.h"
#include "ui/gl/scoped_binders.h"
#define LOGF(level) LOG(level) << __FUNCTION__ << "(): "
@@ -169,14 +171,12 @@ struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef {
BitstreamBufferRef(
base::WeakPtr<VideoDecodeAccelerator::Client>& client,
const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
- base::SharedMemory* shm,
- size_t size,
+ SharedMemoryRegion* shm,
int32_t input_id);
~BitstreamBufferRef();
const base::WeakPtr<VideoDecodeAccelerator::Client> client;
const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner;
- const scoped_ptr<base::SharedMemory> shm;
- const size_t size;
+ const scoped_ptr<SharedMemoryRegion> shm;
off_t bytes_used;
const int32_t input_id;
};
@@ -184,13 +184,11 @@ struct V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef {
V4L2SliceVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
base::WeakPtr<VideoDecodeAccelerator::Client>& client,
const scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
- base::SharedMemory* shm,
- size_t size,
+ SharedMemoryRegion* shm,
int32_t input_id)
: client(client),
client_task_runner(client_task_runner),
shm(shm),
- size(size),
bytes_used(0),
input_id(input_id) {}
@@ -382,15 +380,11 @@ V4L2VP8Picture::~V4L2VP8Picture() {
V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
const scoped_refptr<V4L2Device>& device,
EGLDisplay egl_display,
- EGLContext egl_context,
- const base::WeakPtr<Client>& io_client,
- const base::Callback<bool(void)>& make_context_current,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb)
: input_planes_count_(0),
output_planes_count_(0),
child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- io_task_runner_(io_task_runner),
- io_client_(io_client),
device_(device),
decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"),
device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"),
@@ -406,9 +400,9 @@ V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
surface_set_change_pending_(false),
picture_clearing_count_(0),
pictures_assigned_(false, false),
- make_context_current_(make_context_current),
egl_display_(egl_display),
- egl_context_(egl_context),
+ get_gl_context_cb_(get_gl_context_cb),
+ make_context_current_cb_(make_context_current_cb),
weak_this_factory_(this) {
weak_this_ = weak_this_factory_.GetWeakPtr();
}
@@ -444,6 +438,11 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
DCHECK(child_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, kUninitialized);
+ if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
if (config.is_encrypted) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -459,6 +458,14 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
client_ptr_factory_.reset(
new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client));
client_ = client_ptr_factory_->GetWeakPtr();
+ // If we haven't been set up to decode on separate thread via
+ // TryToSetupDecodeOnSeparateThread(), use the main thread/client for
+ // decode tasks.
+ if (!decode_task_runner_) {
+ decode_task_runner_ = child_task_runner_;
+ DCHECK(!decode_client_);
+ decode_client_ = client_;
+ }
video_profile_ = config.profile;
@@ -485,7 +492,7 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
}
// We need the context to be initialized to query extensions.
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
LOG(ERROR) << "Initialize(): could not make context current";
return false;
}
@@ -750,7 +757,7 @@ bool V4L2SliceVideoDecodeAccelerator::CreateOutputBuffers() {
child_task_runner_->PostTask(
FROM_HERE,
base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers,
- client_, num_pictures, coded_size_,
+ client_, num_pictures, 1, coded_size_,
device_->GetTextureTarget()));
// Wait for the client to call AssignPictureBuffers() on the Child thread.
@@ -1182,7 +1189,15 @@ void V4L2SliceVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
DVLOGF(3) << "input_id=" << bitstream_buffer.id()
<< ", size=" << bitstream_buffer.size();
- DCHECK(io_task_runner_->BelongsToCurrentThread());
+ DCHECK(decode_task_runner_->BelongsToCurrentThread());
+
+ if (bitstream_buffer.id() < 0) {
+ LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+ if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
+ base::SharedMemory::CloseHandle(bitstream_buffer.handle());
+ NOTIFY_ERROR(INVALID_ARGUMENT);
+ return;
+ }
decoder_thread_task_runner_->PostTask(
FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeTask,
@@ -1196,10 +1211,9 @@ void V4L2SliceVideoDecodeAccelerator::DecodeTask(
DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
- io_client_, io_task_runner_,
- new base::SharedMemory(bitstream_buffer.handle(), true),
- bitstream_buffer.size(), bitstream_buffer.id()));
- if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
+ decode_client_, decode_task_runner_,
+ new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id()));
+ if (!bitstream_record->shm->Map()) {
LOGF(ERROR) << "Could not map bitstream_buffer";
NOTIFY_ERROR(UNREADABLE_INPUT);
return;
@@ -1231,7 +1245,7 @@ bool V4L2SliceVideoDecodeAccelerator::TrySetNewBistreamBuffer() {
const uint8_t* const data = reinterpret_cast<const uint8_t*>(
decoder_current_bitstream_buffer_->shm->memory());
- const size_t data_size = decoder_current_bitstream_buffer_->size;
+ const size_t data_size = decoder_current_bitstream_buffer_->shm->size();
decoder_->SetStream(data, data_size);
return true;
@@ -1442,8 +1456,9 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers(
return;
}
- if (!make_context_current_.Run()) {
- DLOG(ERROR) << "could not make context current";
+ gfx::GLContext* gl_context = get_gl_context_cb_.Run();
+ if (!gl_context || !make_context_current_cb_.Run()) {
+ DLOG(ERROR) << "No GL context";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
}
@@ -1481,13 +1496,10 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffers(
DCHECK_EQ(output_record.picture_id, -1);
DCHECK_EQ(output_record.cleared, false);
- EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
- egl_context_,
- buffers[i].texture_id(),
- coded_size_,
- i,
- output_format_fourcc_,
- output_planes_count_);
+ DCHECK_LE(1u, buffers[i].texture_ids().size());
+ EGLImageKHR egl_image = device_->CreateEGLImage(
+ egl_display_, gl_context->GetHandle(), buffers[i].texture_ids()[0],
+ buffers[i].size(), i, output_format_fourcc_, output_planes_count_);
if (egl_image == EGL_NO_IMAGE_KHR) {
LOGF(ERROR) << "Could not create EGLImageKHR";
// Ownership of EGLImages allocated in previous iterations of this loop
@@ -1511,7 +1523,7 @@ void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer(
DCHECK(child_task_runner_->BelongsToCurrentThread());
DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id;
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
LOGF(ERROR) << "could not make context current";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
@@ -1587,7 +1599,7 @@ void V4L2SliceVideoDecodeAccelerator::FlushTask() {
// which - when reached - will trigger flush sequence.
decoder_input_queue_.push(
linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
- io_client_, io_task_runner_, nullptr, 0, kFlushBufferId)));
+ decode_client_, decode_task_runner_, nullptr, kFlushBufferId)));
return;
}
@@ -2501,12 +2513,14 @@ void V4L2SliceVideoDecodeAccelerator::SendPictureReady() {
bool cleared = pending_picture_ready_.front().cleared;
const media::Picture& picture = pending_picture_ready_.front().picture;
if (cleared && picture_clearing_count_ == 0) {
- DVLOGF(4) << "Posting picture ready to IO for: "
+ DVLOGF(4) << "Posting picture ready to decode task runner for: "
<< picture.picture_buffer_id();
- // This picture is cleared. Post it to IO thread to reduce latency. This
- // should be the case after all pictures are cleared at the beginning.
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
+ // This picture is cleared. It can be posted to a thread different than
+ // the main GPU thread to reduce latency. This should be the case after
+ // all pictures are cleared at the beginning.
+ decode_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Client::PictureReady, decode_client_, picture));
pending_picture_ready_.pop();
} else if (!cleared || resetting_or_flushing) {
DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared
@@ -2544,7 +2558,11 @@ void V4L2SliceVideoDecodeAccelerator::PictureCleared() {
SendPictureReady();
}
-bool V4L2SliceVideoDecodeAccelerator::CanDecodeOnIOThread() {
+bool V4L2SliceVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
+ decode_client_ = decode_client_;
+ decode_task_runner_ = decode_task_runner;
return true;
}
diff --git a/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h b/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
index dd72eb7a6dd..cc11da302a1 100644
--- a/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
@@ -19,6 +19,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "content/common/gpu/media/h264_decoder.h"
#include "content/common/gpu/media/v4l2_device.h"
#include "content/common/gpu/media/vp8_decoder.h"
@@ -38,10 +39,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
V4L2SliceVideoDecodeAccelerator(
const scoped_refptr<V4L2Device>& device,
EGLDisplay egl_display,
- EGLContext egl_context,
- const base::WeakPtr<Client>& io_client_,
- const base::Callback<bool(void)>& make_context_current,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb);
~V4L2SliceVideoDecodeAccelerator() override;
// media::VideoDecodeAccelerator implementation.
@@ -53,7 +52,10 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
static media::VideoDecodeAccelerator::SupportedProfiles
GetSupportedProfiles();
@@ -282,8 +284,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// GPU Child thread task runner.
const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_;
- // IO thread task runner.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ // Task runner Decode() and PictureReady() run on.
+ scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_;
// WeakPtr<> pointing to |this| for use in posting tasks from the decoder or
// device worker threads back to the child thread.
@@ -295,8 +297,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator::Client>>
client_ptr_factory_;
base::WeakPtr<VideoDecodeAccelerator::Client> client_;
- // Callbacks to |io_client_| must be executed on |io_task_runner_|.
- base::WeakPtr<Client> io_client_;
+ // Callbacks to |decode_client_| must be executed on |decode_task_runner_|.
+ base::WeakPtr<Client> decode_client_;
// V4L2 device in use.
scoped_refptr<V4L2Device> device_;
@@ -381,12 +383,13 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// to avoid races with potential Reset requests.
base::WaitableEvent pictures_assigned_;
- // Make the GL context current callback.
- base::Callback<bool(void)> make_context_current_;
-
// EGL state
EGLDisplay egl_display_;
- EGLContext egl_context_;
+
+ // Callback to get current GLContext.
+ GetGLContextCallback get_gl_context_cb_;
+ // Callback to set the correct gl context.
+ MakeGLContextCurrentCallback make_context_current_cb_;
// The WeakPtrFactory for |weak_this_|.
base::WeakPtrFactory<V4L2SliceVideoDecodeAccelerator> weak_this_factory_;
diff --git a/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.cc
index f9311257ed7..719dbf7a80f 100644
--- a/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -15,16 +15,17 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
#include "media/base/media_switches.h"
#include "media/filters/h264_parser.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gl/gl_context.h"
#include "ui/gl/scoped_binders.h"
#define NOTIFY_ERROR(x) \
@@ -65,14 +66,12 @@ struct V4L2VideoDecodeAccelerator::BitstreamBufferRef {
BitstreamBufferRef(
base::WeakPtr<Client>& client,
scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
- base::SharedMemory* shm,
- size_t size,
+ scoped_ptr<SharedMemoryRegion> shm,
int32_t input_id);
~BitstreamBufferRef();
const base::WeakPtr<Client> client;
const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner;
- const scoped_ptr<base::SharedMemory> shm;
- const size_t size;
+ const scoped_ptr<SharedMemoryRegion> shm;
size_t bytes_used;
const int32_t input_id;
};
@@ -94,13 +93,11 @@ struct V4L2VideoDecodeAccelerator::PictureRecord {
V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
base::WeakPtr<Client>& client,
scoped_refptr<base::SingleThreadTaskRunner>& client_task_runner,
- base::SharedMemory* shm,
- size_t size,
+ scoped_ptr<SharedMemoryRegion> shm,
int32_t input_id)
: client(client),
client_task_runner(client_task_runner),
- shm(shm),
- size(size),
+ shm(std::move(shm)),
bytes_used(0),
input_id(input_id) {}
@@ -157,14 +154,10 @@ V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
EGLDisplay egl_display,
- EGLContext egl_context,
- const base::WeakPtr<Client>& io_client,
- const base::Callback<bool(void)>& make_context_current,
- const scoped_refptr<V4L2Device>& device,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const scoped_refptr<V4L2Device>& device)
: child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- io_task_runner_(io_task_runner),
- io_client_(io_client),
decoder_thread_("V4L2DecoderThread"),
decoder_state_(kUninitialized),
device_(device),
@@ -184,9 +177,9 @@ V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
picture_clearing_count_(0),
pictures_assigned_(false, false),
device_poll_thread_("V4L2DevicePollThread"),
- make_context_current_(make_context_current),
egl_display_(egl_display),
- egl_context_(egl_context),
+ get_gl_context_cb_(get_gl_context_cb),
+ make_context_current_cb_(make_context_current_cb),
video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
output_format_fourcc_(0),
weak_this_factory_(this) {
@@ -212,6 +205,11 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
DCHECK(child_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(decoder_state_, kUninitialized);
+ if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
if (config.is_encrypted) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -226,6 +224,14 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
client_ = client_ptr_factory_->GetWeakPtr();
+ // If we haven't been set up to decode on separate thread via
+ // TryToSetupDecodeOnSeparateThread(), use the main thread/client for
+ // decode tasks.
+ if (!decode_task_runner_) {
+ decode_task_runner_ = child_task_runner_;
+ DCHECK(!decode_client_);
+ decode_client_ = client_;
+ }
video_profile_ = config.profile;
@@ -235,7 +241,7 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
}
// We need the context to be initialized to query extensions.
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
LOG(ERROR) << "Initialize(): could not make context current";
return false;
}
@@ -253,16 +259,9 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
- // This cap combination is deprecated, but some older drivers may still be
- // returning it.
- const __u32 kCapsRequiredCompat = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
- V4L2_CAP_VIDEO_OUTPUT_MPLANE |
- V4L2_CAP_STREAMING;
- if ((caps.capabilities & kCapsRequiredCompat) != kCapsRequiredCompat) {
- LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
- ", caps check failed: 0x" << std::hex << caps.capabilities;
- return false;
- }
+ LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
+ ", caps check failed: 0x" << std::hex << caps.capabilities;
+ return false;
}
if (!SetupFormats())
@@ -303,7 +302,15 @@ void V4L2VideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
<< ", size=" << bitstream_buffer.size();
- DCHECK(io_task_runner_->BelongsToCurrentThread());
+ DCHECK(decode_task_runner_->BelongsToCurrentThread());
+
+ if (bitstream_buffer.id() < 0) {
+ LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+ if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
+ base::SharedMemory::CloseHandle(bitstream_buffer.handle());
+ NOTIFY_ERROR(INVALID_ARGUMENT);
+ return;
+ }
// DecodeTask() will take care of running a DecodeBufferTask().
decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
@@ -327,7 +334,8 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
return;
}
- if (!make_context_current_.Run()) {
+ gfx::GLContext* gl_context = get_gl_context_cb_.Run();
+ if (!gl_context || !make_context_current_cb_.Run()) {
LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
@@ -365,14 +373,11 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
DCHECK_EQ(output_record.egl_sync, EGL_NO_SYNC_KHR);
DCHECK_EQ(output_record.picture_id, -1);
DCHECK_EQ(output_record.cleared, false);
+ DCHECK_LE(1u, buffers[i].texture_ids().size());
- EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
- egl_context_,
- buffers[i].texture_id(),
- coded_size_,
- i,
- output_format_fourcc_,
- output_planes_count_);
+ EGLImageKHR egl_image = device_->CreateEGLImage(
+ egl_display_, gl_context->GetHandle(), buffers[i].texture_ids()[0],
+ coded_size_, i, output_format_fourcc_, output_planes_count_);
if (egl_image == EGL_NO_IMAGE_KHR) {
LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
// Ownership of EGLImages allocated in previous iterations of this loop
@@ -397,7 +402,7 @@ void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
// Must be run on child thread, as we'll insert a sync in the EGL context.
DCHECK(child_task_runner_->BelongsToCurrentThread());
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
@@ -458,7 +463,13 @@ void V4L2VideoDecodeAccelerator::Destroy() {
delete this;
}
-bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
+bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
+ decode_client_ = decode_client_;
+ decode_task_runner_ = decode_task_runner;
+ return true;
+}
// static
media::VideoDecodeAccelerator::SupportedProfiles
@@ -480,10 +491,11 @@ void V4L2VideoDecodeAccelerator::DecodeTask(
bitstream_buffer.id());
scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
- io_client_, io_task_runner_,
- new base::SharedMemory(bitstream_buffer.handle(), true),
- bitstream_buffer.size(), bitstream_buffer.id()));
- if (!bitstream_record->shm->Map(bitstream_buffer.size())) {
+ decode_client_, decode_task_runner_,
+ scoped_ptr<SharedMemoryRegion>(
+ new SharedMemoryRegion(bitstream_buffer, true)),
+ bitstream_buffer.id()));
+ if (!bitstream_record->shm->Map()) {
LOG(ERROR) << "Decode(): could not map bitstream_buffer";
NOTIFY_ERROR(UNREADABLE_INPUT);
return;
@@ -542,54 +554,51 @@ void V4L2VideoDecodeAccelerator::DecodeBufferTask() {
// Setup to use the next buffer.
decoder_current_bitstream_buffer_.reset(buffer_ref.release());
decoder_input_queue_.pop();
- DVLOG(3) << "DecodeBufferTask(): reading input_id="
- << decoder_current_bitstream_buffer_->input_id
- << ", addr=" << (decoder_current_bitstream_buffer_->shm ?
- decoder_current_bitstream_buffer_->shm->memory() :
- NULL)
- << ", size=" << decoder_current_bitstream_buffer_->size;
+ const auto& shm = decoder_current_bitstream_buffer_->shm;
+ if (shm) {
+ DVLOG(3) << "DecodeBufferTask(): reading input_id="
+ << decoder_current_bitstream_buffer_->input_id
+ << ", addr=" << shm->memory() << ", size=" << shm->size();
+ } else {
+ DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId);
+ DVLOG(3) << "DecodeBufferTask(): reading input_id=kFlushBufferId";
+ }
}
bool schedule_task = false;
- const size_t size = decoder_current_bitstream_buffer_->size;
size_t decoded_size = 0;
- if (size == 0) {
- const int32_t input_id = decoder_current_bitstream_buffer_->input_id;
- if (input_id >= 0) {
- // This is a buffer queued from the client that has zero size. Skip.
+ const auto& shm = decoder_current_bitstream_buffer_->shm;
+ if (!shm) {
+ // This is a dummy buffer, queued to flush the pipe. Flush.
+ DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId);
+ // Enqueue a buffer guaranteed to be empty. To do that, we flush the
+ // current input, enqueue no data to the next frame, then flush that down.
+ schedule_task = true;
+ if (decoder_current_input_buffer_ != -1 &&
+ input_buffer_map_[decoder_current_input_buffer_].input_id !=
+ kFlushBufferId)
+ schedule_task = FlushInputFrame();
+
+ if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) {
+ DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer";
+ decoder_partial_frame_pending_ = false;
schedule_task = true;
} else {
- // This is a buffer of zero size, queued to flush the pipe. Flush.
- DCHECK_EQ(decoder_current_bitstream_buffer_->shm.get(),
- static_cast<base::SharedMemory*>(NULL));
- // Enqueue a buffer guaranteed to be empty. To do that, we flush the
- // current input, enqueue no data to the next frame, then flush that down.
- schedule_task = true;
- if (decoder_current_input_buffer_ != -1 &&
- input_buffer_map_[decoder_current_input_buffer_].input_id !=
- kFlushBufferId)
- schedule_task = FlushInputFrame();
-
- if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) {
- DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer";
- decoder_partial_frame_pending_ = false;
- schedule_task = true;
- } else {
- // If we failed to enqueue the empty buffer (due to pipeline
- // backpressure), don't advance the bitstream buffer queue, and don't
- // schedule the next task. This bitstream buffer queue entry will get
- // reprocessed when the pipeline frees up.
- schedule_task = false;
- }
+ // If we failed to enqueue the empty buffer (due to pipeline
+ // backpressure), don't advance the bitstream buffer queue, and don't
+ // schedule the next task. This bitstream buffer queue entry will get
+ // reprocessed when the pipeline frees up.
+ schedule_task = false;
}
+ } else if (shm->size() == 0) {
+ // This is a buffer queued from the client that has zero size. Skip.
+ schedule_task = true;
} else {
// This is a buffer queued from the client, with actual contents. Decode.
const uint8_t* const data =
- reinterpret_cast<const uint8_t*>(
- decoder_current_bitstream_buffer_->shm->memory()) +
+ reinterpret_cast<const uint8_t*>(shm->memory()) +
decoder_current_bitstream_buffer_->bytes_used;
const size_t data_size =
- decoder_current_bitstream_buffer_->size -
- decoder_current_bitstream_buffer_->bytes_used;
+ shm->size() - decoder_current_bitstream_buffer_->bytes_used;
if (!AdvanceFrameFragment(data, data_size, &decoded_size)) {
NOTIFY_ERROR(UNREADABLE_INPUT);
return;
@@ -618,8 +627,8 @@ void V4L2VideoDecodeAccelerator::DecodeBufferTask() {
if (schedule_task) {
decoder_current_bitstream_buffer_->bytes_used += decoded_size;
- if (decoder_current_bitstream_buffer_->bytes_used ==
- decoder_current_bitstream_buffer_->size) {
+ if ((shm ? shm->size() : 0) ==
+ decoder_current_bitstream_buffer_->bytes_used) {
// Our current bitstream buffer is done; return it.
int32_t input_id = decoder_current_bitstream_buffer_->input_id;
DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id;
@@ -1023,14 +1032,7 @@ bool V4L2VideoDecodeAccelerator::DequeueResolutionChangeEvent() {
while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) {
if (ev.type == V4L2_EVENT_SOURCE_CHANGE) {
- uint32_t changes = ev.u.src_change.changes;
- // We used to define source change was always resolution change. The union
- // |ev.u| is not used and it is zero by default. When using the upstream
- // version of the resolution event change, we also need to check
- // |ev.u.src_change.changes| to know what is changed. For API backward
- // compatibility, event is treated as resolution change when all bits in
- // |ev.u.src_change.changes| are cleared.
- if (changes == 0 || (changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
+ if (ev.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) {
DVLOG(3)
<< "DequeueResolutionChangeEvent(): got resolution change event.";
return true;
@@ -1282,7 +1284,7 @@ void V4L2VideoDecodeAccelerator::FlushTask() {
// Queue up an empty buffer -- this triggers the flush.
decoder_input_queue_.push(
linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
- io_client_, io_task_runner_, NULL, 0, kFlushBufferId)));
+ decode_client_, decode_task_runner_, nullptr, kFlushBufferId)));
decoder_flushing_ = true;
SendPictureReady(); // Send all pending PictureReady.
@@ -1886,9 +1888,9 @@ bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() {
<< "buffer_count=" << buffer_count
<< ", coded_size=" << coded_size_.ToString();
child_task_runner_->PostTask(
- FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_,
- buffer_count, coded_size_,
- device_->GetTextureTarget()));
+ FROM_HERE,
+ base::Bind(&Client::ProvidePictureBuffers, client_, buffer_count, 1,
+ coded_size_, device_->GetTextureTarget()));
// Wait for the client to call AssignPictureBuffers() on the Child thread.
// We do this, because if we continue decoding without finishing buffer
@@ -2005,10 +2007,12 @@ void V4L2VideoDecodeAccelerator::SendPictureReady() {
bool cleared = pending_picture_ready_.front().cleared;
const media::Picture& picture = pending_picture_ready_.front().picture;
if (cleared && picture_clearing_count_ == 0) {
- // This picture is cleared. Post it to IO thread to reduce latency. This
- // should be the case after all pictures are cleared at the beginning.
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
+ // This picture is cleared. It can be posted to a thread different than
+ // the main GPU thread to reduce latency. This should be the case after
+ // all pictures are cleared at the beginning.
+ decode_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Client::PictureReady, decode_client_, picture));
pending_picture_ready_.pop();
} else if (!cleared || resetting_or_flushing) {
DVLOG(3) << "SendPictureReady()"
diff --git a/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.h b/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.h
index 3d06665e344..cb749569241 100644
--- a/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/v4l2_video_decode_accelerator.h
@@ -23,6 +23,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "content/common/gpu/media/v4l2_device.h"
#include "media/base/limits.h"
#include "media/base/video_decoder_config.h"
@@ -78,11 +79,9 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator
public:
V4L2VideoDecodeAccelerator(
EGLDisplay egl_display,
- EGLContext egl_context,
- const base::WeakPtr<Client>& io_client_,
- const base::Callback<bool(void)>& make_context_current,
- const scoped_refptr<V4L2Device>& device,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
+ const GetGLContextCallback& get_gl_context_cb,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const scoped_refptr<V4L2Device>& device);
~V4L2VideoDecodeAccelerator() override;
// media::VideoDecodeAccelerator implementation.
@@ -95,7 +94,10 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
static media::VideoDecodeAccelerator::SupportedProfiles
GetSupportedProfiles();
@@ -316,8 +318,8 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator
// Our original calling task runner for the child thread.
scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_;
- // Task runner of the IO thread.
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ // Task runner Decode() and PictureReady() run on.
+ scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_;
// WeakPtr<> pointing to |this| for use in posting tasks from the decoder or
// device worker threads back to the child thread. Because the worker threads
@@ -332,8 +334,8 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator
// child_task_runner_.
scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
base::WeakPtr<Client> client_;
- // Callbacks to |io_client_| must be executed on |io_task_runner_|.
- base::WeakPtr<Client> io_client_;
+ // Callbacks to |decode_client_| must be executed on |decode_task_runner_|.
+ base::WeakPtr<Client> decode_client_;
//
// Decoder state, owned and operated by decoder_thread_.
@@ -438,12 +440,13 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator
// Other state, held by the child (main) thread.
//
- // Make our context current before running any EGL entry points.
- base::Callback<bool(void)> make_context_current_;
-
// EGL state
EGLDisplay egl_display_;
- EGLContext egl_context_;
+
+ // Callback to get current GLContext.
+ GetGLContextCallback get_gl_context_cb_;
+ // Callback to set the correct gl context.
+ MakeGLContextCurrentCallback make_context_current_cb_;
// The codec we'll be decoding for.
media::VideoCodecProfile video_profile_;
diff --git a/chromium/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/chromium/content/common/gpu/media/v4l2_video_encode_accelerator.cc
index 98f4e48db35..d724d8dea40 100644
--- a/chromium/content/common/gpu/media/v4l2_video_encode_accelerator.cc
+++ b/chromium/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -17,8 +17,8 @@
#include "base/numerics/safe_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
-#include "content/public/common/content_switches.h"
#include "media/base/bitstream_buffer.h"
#define NOTIFY_ERROR(x) \
@@ -51,13 +51,10 @@
namespace content {
struct V4L2VideoEncodeAccelerator::BitstreamBufferRef {
- BitstreamBufferRef(int32_t id,
- scoped_ptr<base::SharedMemory> shm,
- size_t size)
- : id(id), shm(std::move(shm)), size(size) {}
+ BitstreamBufferRef(int32_t id, scoped_ptr<SharedMemoryRegion> shm)
+ : id(id), shm(std::move(shm)) {}
const int32_t id;
- const scoped_ptr<base::SharedMemory> shm;
- const size_t size;
+ const scoped_ptr<SharedMemoryRegion> shm;
};
V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) {
@@ -128,20 +125,13 @@ bool V4L2VideoEncodeAccelerator::Initialize(
const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
- // This cap combination is deprecated, but some older drivers may still be
- // returning it.
- const __u32 kCapsRequiredCompat = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
- V4L2_CAP_VIDEO_OUTPUT_MPLANE |
- V4L2_CAP_STREAMING;
- if ((caps.capabilities & kCapsRequiredCompat) != kCapsRequiredCompat) {
- LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
- "caps check failed: 0x" << std::hex << caps.capabilities;
- return false;
- }
+ LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
+ "caps check failed: 0x" << std::hex << caps.capabilities;
+ return false;
}
if (!SetFormats(input_format, output_profile)) {
- LOG(ERROR) << "Failed setting up formats";
+ DLOG(ERROR) << "Failed setting up formats";
return false;
}
@@ -231,15 +221,14 @@ void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer(
return;
}
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(buffer.handle(), false));
- if (!shm->Map(buffer.size())) {
+ scoped_ptr<SharedMemoryRegion> shm(new SharedMemoryRegion(buffer, false));
+ if (!shm->Map()) {
NOTIFY_ERROR(kPlatformFailureError);
return;
}
scoped_ptr<BitstreamBufferRef> buffer_ref(
- new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size()));
+ new BitstreamBufferRef(buffer.id(), std::move(shm)));
encoder_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
@@ -318,7 +307,13 @@ V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
profiles.push_back(profile);
break;
case V4L2_PIX_FMT_VP9:
- profile.profile = media::VP9PROFILE_ANY;
+ profile.profile = media::VP9PROFILE_PROFILE0;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE1;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE2;
+ profiles.push_back(profile);
+ profile.profile = media::VP9PROFILE_PROFILE3;
profiles.push_back(profile);
break;
}
@@ -365,13 +360,21 @@ void V4L2VideoEncodeAccelerator::EncodeTask(
std::vector<struct v4l2_ext_control> ctrls;
struct v4l2_ext_control ctrl;
memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE;
- ctrl.value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME;
+ ctrl.id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME;
ctrls.push_back(ctrl);
if (!SetExtCtrls(ctrls)) {
- LOG(ERROR) << "Failed requesting keyframe";
- NOTIFY_ERROR(kPlatformFailureError);
- return;
+ // Some platforms still use the old control. Fallback before they are
+ // updated.
+ ctrls.clear();
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE;
+ ctrl.value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME;
+ ctrls.push_back(ctrl);
+ if (!SetExtCtrls(ctrls)) {
+ LOG(ERROR) << "Failed requesting keyframe";
+ NOTIFY_ERROR(kPlatformFailureError);
+ return;
+ }
}
}
}
@@ -893,7 +896,7 @@ bool V4L2VideoEncodeAccelerator::NegotiateInputFormat(
uint32_t input_format_fourcc =
V4L2Device::VideoPixelFormatToV4L2PixFmt(input_format);
if (!input_format_fourcc) {
- LOG(ERROR) << "Unsupported input format";
+ LOG(ERROR) << "Unsupported input format" << input_format_fourcc;
return false;
}
@@ -913,8 +916,10 @@ bool V4L2VideoEncodeAccelerator::NegotiateInputFormat(
input_format_fourcc = device_->PreferredInputFormat();
input_format =
V4L2Device::V4L2PixFmtToVideoPixelFormat(input_format_fourcc);
- if (input_format == media::PIXEL_FORMAT_UNKNOWN)
+ if (input_format == media::PIXEL_FORMAT_UNKNOWN) {
+ LOG(ERROR) << "Unsupported input format" << input_format_fourcc;
return false;
+ }
input_planes_count = media::VideoFrame::NumPlanes(input_format);
DCHECK_LE(input_planes_count, static_cast<size_t>(VIDEO_MAX_PLANES));
@@ -930,9 +935,14 @@ bool V4L2VideoEncodeAccelerator::NegotiateInputFormat(
DCHECK_EQ(format.fmt.pix_mp.num_planes, input_planes_count);
}
- // Take device-adjusted sizes for allocated size.
+ // Take device-adjusted sizes for allocated size. If the size is adjusted
+ // down, it means the input is too big and the hardware does not support it.
input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format);
- DCHECK(gfx::Rect(input_allocated_size_).Contains(gfx::Rect(visible_size_)));
+ if (!gfx::Rect(input_allocated_size_).Contains(gfx::Rect(visible_size_))) {
+ DVLOG(1) << "Input size too big " << visible_size_.ToString()
+ << ", adjusted to " << input_allocated_size_.ToString();
+ return false;
+ }
device_input_format_ = input_format;
input_planes_count_ = input_planes_count;
@@ -1031,30 +1041,35 @@ bool V4L2VideoEncodeAccelerator::InitControls() {
ctrls.push_back(ctrl);
}
- // Enable "tight" bitrate mode. For this to work properly, frame- and mb-level
- // bitrate controls have to be enabled as well.
+ // Enable macroblock-level bitrate control.
memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+ ctrl.id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
ctrl.value = 1;
ctrls.push_back(ctrl);
- // Force bitrate control to average over a GOP (for tight bitrate
- // tolerance).
+ // Disable periodic key frames.
memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
- ctrl.value = 1;
+ ctrl.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+ ctrl.value = 0;
ctrls.push_back(ctrl);
- // Enable macroblock-level bitrate control.
+ // Ignore return value as these controls are optional.
+ SetExtCtrls(ctrls);
+
+ // Optional Exynos specific controls.
+ ctrls.clear();
+ // Enable "tight" bitrate mode. For this to work properly, frame- and mb-level
+ // bitrate controls have to be enabled as well.
memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
+ ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ctrl.value = 1;
ctrls.push_back(ctrl);
- // Disable periodic key frames.
+ // Force bitrate control to average over a GOP (for tight bitrate
+ // tolerance).
memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
- ctrl.value = 0;
+ ctrl.id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
+ ctrl.value = 1;
ctrls.push_back(ctrl);
// Ignore return value as these controls are optional.
diff --git a/chromium/content/common/gpu/media/vaapi_drm_picture.cc b/chromium/content/common/gpu/media/vaapi_drm_picture.cc
index f20716426fd..ab5a4f28b1a 100644
--- a/chromium/content/common/gpu/media/vaapi_drm_picture.cc
+++ b/chromium/content/common/gpu/media/vaapi_drm_picture.cc
@@ -27,16 +27,16 @@ namespace content {
VaapiDrmPicture::VaapiDrmPicture(
const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)>& make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size)
: VaapiPicture(picture_buffer_id, texture_id, size),
vaapi_wrapper_(vaapi_wrapper),
- make_context_current_(make_context_current) {}
+ make_context_current_cb_(make_context_current_cb) {}
VaapiDrmPicture::~VaapiDrmPicture() {
- if (gl_image_ && make_context_current_.Run()) {
+ if (gl_image_ && make_context_current_cb_.Run()) {
gl_image_->ReleaseTexImage(GL_TEXTURE_EXTERNAL_OES);
gl_image_->Destroy(true);
@@ -67,7 +67,7 @@ bool VaapiDrmPicture::Initialize() {
pixmap_->SetProcessingCallback(
base::Bind(&VaapiWrapper::ProcessPixmap, vaapi_wrapper_));
- if (!make_context_current_.Run())
+ if (!make_context_current_cb_.Run())
return false;
gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES,
diff --git a/chromium/content/common/gpu/media/vaapi_drm_picture.h b/chromium/content/common/gpu/media/vaapi_drm_picture.h
index 066192b25ca..7f5fc8a1780 100644
--- a/chromium/content/common/gpu/media/vaapi_drm_picture.h
+++ b/chromium/content/common/gpu/media/vaapi_drm_picture.h
@@ -11,7 +11,6 @@
#include <stdint.h>
-#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -35,7 +34,7 @@ class VaapiWrapper;
class VaapiDrmPicture : public VaapiPicture {
public:
VaapiDrmPicture(const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)>& make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size);
@@ -52,7 +51,7 @@ class VaapiDrmPicture : public VaapiPicture {
private:
scoped_refptr<VaapiWrapper> vaapi_wrapper_;
- base::Callback<bool(void)> make_context_current_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
// Ozone buffer, the storage of the EGLImage and the VASurface.
scoped_refptr<ui::NativePixmap> pixmap_;
diff --git a/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc b/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc
index 8efb362180d..a0cbc6e059d 100644
--- a/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.cc
@@ -13,8 +13,9 @@
#include "base/metrics/histogram.h"
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/vaapi_picture.h"
+#include "gpu/ipc/service/gpu_channel.h"
#include "media/base/video_frame.h"
#include "media/filters/jpeg_parser.h"
#include "third_party/libyuv/include/libyuv.h"
@@ -76,10 +77,10 @@ static unsigned int VaSurfaceFormatForJpeg(
} // namespace
VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest(
- const media::BitstreamBuffer& bitstream_buffer,
- scoped_ptr<base::SharedMemory> shm,
+ int32_t bitstream_buffer_id,
+ scoped_ptr<SharedMemoryRegion> shm,
const scoped_refptr<media::VideoFrame>& video_frame)
- : bitstream_buffer(bitstream_buffer),
+ : bitstream_buffer_id(bitstream_buffer_id),
shm(std::move(shm)),
video_frame(video_frame) {}
@@ -226,9 +227,9 @@ void VaapiJpegDecodeAccelerator::DecodeTask(
media::JpegParseResult parse_result;
if (!media::ParseJpegPicture(
reinterpret_cast<const uint8_t*>(request->shm->memory()),
- request->bitstream_buffer.size(), &parse_result)) {
+ request->shm->size(), &parse_result)) {
DLOG(ERROR) << "ParseJpegPicture failed";
- NotifyErrorFromDecoderThread(request->bitstream_buffer.id(),
+ NotifyErrorFromDecoderThread(request->bitstream_buffer_id,
PARSE_JPEG_FAILED);
return;
}
@@ -237,7 +238,7 @@ void VaapiJpegDecodeAccelerator::DecodeTask(
VaSurfaceFormatForJpeg(parse_result.frame_header);
if (!new_va_rt_format) {
DLOG(ERROR) << "Unsupported subsampling";
- NotifyErrorFromDecoderThread(request->bitstream_buffer.id(),
+ NotifyErrorFromDecoderThread(request->bitstream_buffer_id,
UNSUPPORTED_JPEG);
return;
}
@@ -255,7 +256,7 @@ void VaapiJpegDecodeAccelerator::DecodeTask(
if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1,
&va_surfaces)) {
LOG(ERROR) << "Create VA surface failed";
- NotifyErrorFromDecoderThread(request->bitstream_buffer.id(),
+ NotifyErrorFromDecoderThread(request->bitstream_buffer_id,
PLATFORM_FAILURE);
return;
}
@@ -266,15 +267,15 @@ void VaapiJpegDecodeAccelerator::DecodeTask(
if (!VaapiJpegDecoder::Decode(vaapi_wrapper_.get(), parse_result,
va_surface_id_)) {
LOG(ERROR) << "Decode JPEG failed";
- NotifyErrorFromDecoderThread(request->bitstream_buffer.id(),
+ NotifyErrorFromDecoderThread(request->bitstream_buffer_id,
PLATFORM_FAILURE);
return;
}
- if (!OutputPicture(va_surface_id_, request->bitstream_buffer.id(),
+ if (!OutputPicture(va_surface_id_, request->bitstream_buffer_id,
request->video_frame)) {
LOG(ERROR) << "Output picture failed";
- NotifyErrorFromDecoderThread(request->bitstream_buffer.id(),
+ NotifyErrorFromDecoderThread(request->bitstream_buffer_id,
PLATFORM_FAILURE);
return;
}
@@ -289,17 +290,25 @@ void VaapiJpegDecodeAccelerator::Decode(
DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id()
<< " size: " << bitstream_buffer.size();
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(bitstream_buffer.handle(), true));
- if (!shm->Map(bitstream_buffer.size())) {
+ // SharedMemoryRegion will take over the |bitstream_buffer.handle()|.
+ scoped_ptr<SharedMemoryRegion> shm(
+ new SharedMemoryRegion(bitstream_buffer, true));
+
+ if (bitstream_buffer.id() < 0) {
+ LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+ NotifyErrorFromDecoderThread(bitstream_buffer.id(), INVALID_ARGUMENT);
+ return;
+ }
+
+ if (!shm->Map()) {
LOG(ERROR) << "Failed to map input buffer";
NotifyErrorFromDecoderThread(bitstream_buffer.id(), UNREADABLE_INPUT);
return;
}
scoped_ptr<DecodeRequest> request(
- new DecodeRequest(bitstream_buffer, std::move(shm), video_frame));
+ new DecodeRequest(bitstream_buffer.id(), std::move(shm), video_frame));
decoder_task_runner_->PostTask(
FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask,
diff --git a/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h b/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h
index 7d78a5503e9..232b04de829 100644
--- a/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/vaapi_jpeg_decode_accelerator.h
@@ -15,6 +15,7 @@
#include "base/threading/non_thread_safe.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/vaapi_jpeg_decoder.h"
#include "content/common/gpu/media/vaapi_wrapper.h"
#include "media/base/bitstream_buffer.h"
@@ -47,13 +48,13 @@ class CONTENT_EXPORT VaapiJpegDecodeAccelerator
// An input buffer and the corresponding output video frame awaiting
// consumption, provided by the client.
struct DecodeRequest {
- DecodeRequest(const media::BitstreamBuffer& bitstream_buffer,
- scoped_ptr<base::SharedMemory> shm,
+ DecodeRequest(int32_t bitstream_buffer_id,
+ scoped_ptr<SharedMemoryRegion> shm,
const scoped_refptr<media::VideoFrame>& video_frame);
~DecodeRequest();
- media::BitstreamBuffer bitstream_buffer;
- scoped_ptr<base::SharedMemory> shm;
+ int32_t bitstream_buffer_id;
+ scoped_ptr<SharedMemoryRegion> shm;
scoped_refptr<media::VideoFrame> video_frame;
};
diff --git a/chromium/content/common/gpu/media/vaapi_picture.cc b/chromium/content/common/gpu/media/vaapi_picture.cc
index 5222bd23504..cdf8c355974 100644
--- a/chromium/content/common/gpu/media/vaapi_picture.cc
+++ b/chromium/content/common/gpu/media/vaapi_picture.cc
@@ -18,16 +18,16 @@ namespace content {
// static
linked_ptr<VaapiPicture> VaapiPicture::CreatePicture(
const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)> make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size) {
linked_ptr<VaapiPicture> picture;
#if defined(USE_X11)
- picture.reset(new VaapiTFPPicture(vaapi_wrapper, make_context_current,
+ picture.reset(new VaapiTFPPicture(vaapi_wrapper, make_context_current_cb,
picture_buffer_id, texture_id, size));
#elif defined(USE_OZONE)
- picture.reset(new VaapiDrmPicture(vaapi_wrapper, make_context_current,
+ picture.reset(new VaapiDrmPicture(vaapi_wrapper, make_context_current_cb,
picture_buffer_id, texture_id, size));
#endif // USE_X11
diff --git a/chromium/content/common/gpu/media/vaapi_picture.h b/chromium/content/common/gpu/media/vaapi_picture.h
index 921f80344ec..4bd51e11620 100644
--- a/chromium/content/common/gpu/media/vaapi_picture.h
+++ b/chromium/content/common/gpu/media/vaapi_picture.h
@@ -12,11 +12,11 @@
#include <stdint.h>
-#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "ui/gfx/geometry/size.h"
namespace gl {
@@ -52,10 +52,10 @@ class VaapiPicture : public base::NonThreadSafe {
// Create a VaapiPicture of |size| to be associated with
// |picture_buffer_id| and bound to |texture_id|.
- // |make_context_current| is provided for the GL operations.
+ // |make_context_current_cb| is provided for the GL operations.
static linked_ptr<VaapiPicture> CreatePicture(
const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)> make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size);
diff --git a/chromium/content/common/gpu/media/vaapi_tfp_picture.cc b/chromium/content/common/gpu/media/vaapi_tfp_picture.cc
index 3de593b62fd..074ba98ed73 100644
--- a/chromium/content/common/gpu/media/vaapi_tfp_picture.cc
+++ b/chromium/content/common/gpu/media/vaapi_tfp_picture.cc
@@ -14,18 +14,18 @@ namespace content {
VaapiTFPPicture::VaapiTFPPicture(
const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)> make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size)
: VaapiPicture(picture_buffer_id, texture_id, size),
vaapi_wrapper_(vaapi_wrapper),
- make_context_current_(make_context_current),
+ make_context_current_cb_(make_context_current_cb),
x_display_(gfx::GetXDisplay()),
x_pixmap_(0) {}
VaapiTFPPicture::~VaapiTFPPicture() {
- if (glx_image_.get() && make_context_current_.Run()) {
+ if (glx_image_.get() && make_context_current_cb_.Run()) {
glx_image_->ReleaseTexImage(GL_TEXTURE_2D);
glx_image_->Destroy(true);
DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR));
@@ -36,7 +36,7 @@ VaapiTFPPicture::~VaapiTFPPicture() {
}
bool VaapiTFPPicture::Initialize() {
- if (!make_context_current_.Run())
+ if (!make_context_current_cb_.Run())
return false;
XWindowAttributes win_attr;
diff --git a/chromium/content/common/gpu/media/vaapi_tfp_picture.h b/chromium/content/common/gpu/media/vaapi_tfp_picture.h
index 3b66e10800b..5ef35653202 100644
--- a/chromium/content/common/gpu/media/vaapi_tfp_picture.h
+++ b/chromium/content/common/gpu/media/vaapi_tfp_picture.h
@@ -11,7 +11,6 @@
#include <stdint.h>
-#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/gpu/media/vaapi_picture.h"
@@ -34,7 +33,7 @@ class VaapiWrapper;
class VaapiTFPPicture : public VaapiPicture {
public:
VaapiTFPPicture(const scoped_refptr<VaapiWrapper>& vaapi_wrapper,
- const base::Callback<bool(void)> make_context_current,
+ const MakeGLContextCurrentCallback& make_context_current_cb,
int32_t picture_buffer_id,
uint32_t texture_id,
const gfx::Size& size);
@@ -50,7 +49,7 @@ class VaapiTFPPicture : public VaapiPicture {
private:
scoped_refptr<VaapiWrapper> vaapi_wrapper_;
- base::Callback<bool(void)> make_context_current_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
Display* x_display_;
Pixmap x_pixmap_;
diff --git a/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.cc
index 271a0f7a1c9..d8caeec94da 100644
--- a/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -14,12 +14,12 @@
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/media/accelerated_video_decoder.h"
#include "content/common/gpu/media/h264_decoder.h"
#include "content/common/gpu/media/vaapi_picture.h"
#include "content/common/gpu/media/vp8_decoder.h"
#include "content/common/gpu/media/vp9_decoder.h"
+#include "gpu/ipc/service/gpu_channel.h"
#include "media/base/bind_to_current_loop.h"
#include "media/video/picture.h"
#include "third_party/libva/va/va_dec_vp8.h"
@@ -256,8 +256,7 @@ class VaapiVideoDecodeAccelerator::VaapiVP9Accelerator
DISALLOW_COPY_AND_ASSIGN(VaapiVP9Accelerator);
};
-VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0), size(0) {
-}
+VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0) {}
VaapiVideoDecodeAccelerator::InputBuffer::~InputBuffer() {
}
@@ -293,11 +292,9 @@ VaapiPicture* VaapiVideoDecodeAccelerator::PictureById(
}
VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>&
- bind_image)
- : make_context_current_(make_context_current),
- state_(kUninitialized),
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb)
+ : state_(kUninitialized),
input_ready_(&lock_),
surfaces_available_(&lock_),
message_loop_(base::MessageLoop::current()),
@@ -307,7 +304,8 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
finish_flush_pending_(false),
awaiting_va_surfaces_recycle_(false),
requested_num_pics_(0),
- bind_image_(bind_image),
+ make_context_current_cb_(make_context_current_cb),
+ bind_image_cb_(bind_image_cb),
weak_this_factory_(this) {
weak_this_ = weak_this_factory_.GetWeakPtr();
va_surface_release_cb_ = media::BindToCurrentLoop(
@@ -322,6 +320,11 @@ bool VaapiVideoDecodeAccelerator::Initialize(const Config& config,
Client* client) {
DCHECK_EQ(message_loop_, base::MessageLoop::current());
+ if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
if (config.is_encrypted) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -447,10 +450,10 @@ void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id()
<< " size: " << (int)bitstream_buffer.size();
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(bitstream_buffer.handle(), true));
- RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()),
- "Failed to map input buffer", UNREADABLE_INPUT,);
+ scoped_ptr<SharedMemoryRegion> shm(
+ new SharedMemoryRegion(bitstream_buffer, true));
+ RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(), "Failed to map input buffer",
+ UNREADABLE_INPUT, );
base::AutoLock auto_lock(lock_);
@@ -458,7 +461,6 @@ void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
linked_ptr<InputBuffer> input_buffer(new InputBuffer());
input_buffer->shm.reset(shm.release());
input_buffer->id = bitstream_buffer.id();
- input_buffer->size = bitstream_buffer.size();
++num_stream_bufs_at_decoder_;
TRACE_COUNTER1("Video Decoder", "Stream buffers at decoder",
@@ -497,13 +499,12 @@ bool VaapiVideoDecodeAccelerator::GetInputBuffer_Locked() {
curr_input_buffer_ = input_buffers_.front();
input_buffers_.pop();
- DVLOG(4) << "New current bitstream buffer, id: "
- << curr_input_buffer_->id
- << " size: " << curr_input_buffer_->size;
+ DVLOG(4) << "New current bitstream buffer, id: " << curr_input_buffer_->id
+ << " size: " << curr_input_buffer_->shm->size();
decoder_->SetStream(
static_cast<uint8_t*>(curr_input_buffer_->shm->memory()),
- curr_input_buffer_->size);
+ curr_input_buffer_->shm->size());
return true;
default:
@@ -663,7 +664,7 @@ void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() {
message_loop_->PostTask(
FROM_HERE,
base::Bind(&Client::ProvidePictureBuffers, client_, requested_num_pics_,
- requested_pic_size_, VaapiPicture::GetGLTextureTarget()));
+ 1, requested_pic_size_, VaapiPicture::GetGLTextureTarget()));
}
void VaapiVideoDecodeAccelerator::Decode(
@@ -673,6 +674,12 @@ void VaapiVideoDecodeAccelerator::Decode(
TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "Buffer id",
bitstream_buffer.id());
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ bitstream_buffer.id() >= 0 &&
+ base::SharedMemory::IsHandleValid(bitstream_buffer.handle()),
+ "Invalid bitstream_buffer, id: " << bitstream_buffer.id(),
+ INVALID_ARGUMENT, );
+
// We got a new input buffer from the client, map it and queue for later use.
MapAndQueueNewInputBuffer(bitstream_buffer);
@@ -734,18 +741,22 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
DCHECK_EQ(va_surface_ids.size(), buffers.size());
for (size_t i = 0; i < buffers.size(); ++i) {
+ DCHECK_LE(1u, buffers[i].texture_ids().size());
DVLOG(2) << "Assigning picture id: " << buffers[i].id()
- << " to texture id: " << buffers[i].texture_id()
+ << " to texture id: " << buffers[i].texture_ids()[0]
<< " VASurfaceID: " << va_surface_ids[i];
linked_ptr<VaapiPicture> picture(VaapiPicture::CreatePicture(
- vaapi_wrapper_, make_context_current_, buffers[i].id(),
- buffers[i].texture_id(), requested_pic_size_));
+ vaapi_wrapper_, make_context_current_cb_, buffers[i].id(),
+ buffers[i].texture_ids()[0], requested_pic_size_));
scoped_refptr<gl::GLImage> image = picture->GetImageToBind();
if (image) {
- bind_image_.Run(buffers[i].internal_texture_id(),
- VaapiPicture::GetGLTextureTarget(), image);
+ DCHECK_LE(1u, buffers[i].internal_texture_ids().size());
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ bind_image_cb_.Run(buffers[i].internal_texture_ids()[0],
+ VaapiPicture::GetGLTextureTarget(), image, true),
+ "Failed to bind image", PLATFORM_FAILURE, );
}
RETURN_AND_NOTIFY_ON_FAILURE(
@@ -960,7 +971,9 @@ void VaapiVideoDecodeAccelerator::Destroy() {
delete this;
}
-bool VaapiVideoDecodeAccelerator::CanDecodeOnIOThread() {
+bool VaapiVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
return false;
}
diff --git a/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.h b/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.h
index 11cc082a627..f9cfb90376c 100644
--- a/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.h
+++ b/chromium/content/common/gpu/media/vaapi_video_decode_accelerator.h
@@ -20,13 +20,14 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
-#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "content/common/gpu/media/vaapi_wrapper.h"
#include "media/base/bitstream_buffer.h"
#include "media/video/picture.h"
@@ -55,9 +56,9 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator
class VaapiDecodeSurface;
VaapiVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- const base::Callback<
- void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& bind_image);
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb);
+
~VaapiVideoDecodeAccelerator() override;
// media::VideoDecodeAccelerator implementation.
@@ -69,7 +70,10 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
static media::VideoDecodeAccelerator::SupportedProfiles
GetSupportedProfiles();
@@ -180,10 +184,6 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator
// available.
scoped_refptr<VaapiDecodeSurface> CreateSurface();
-
- // Client-provided GL state.
- base::Callback<bool(void)> make_context_current_;
-
// VAVDA state.
enum State {
// Initialize() not called yet or failed.
@@ -210,8 +210,7 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator
~InputBuffer();
int32_t id;
- size_t size;
- scoped_ptr<base::SharedMemory> shm;
+ scoped_ptr<SharedMemoryRegion> shm;
};
// Queue for incoming input buffers.
@@ -305,10 +304,11 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator
size_t requested_num_pics_;
gfx::Size requested_pic_size_;
- // Binds the provided GLImage to a givenr client texture ID & texture target
- // combination in GLES.
- base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>
- bind_image_;
+ // Callback to make GL context current.
+ MakeGLContextCurrentCallback make_context_current_cb_;
+
+ // Callback to bind a GLImage to a given texture.
+ BindGLImageCallback bind_image_cb_;
// The WeakPtrFactory for |weak_this_|.
base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
diff --git a/chromium/content/common/gpu/media/vaapi_video_encode_accelerator.cc b/chromium/content/common/gpu/media/vaapi_video_encode_accelerator.cc
index 049cd7a5547..520d411e21b 100644
--- a/chromium/content/common/gpu/media/vaapi_video_encode_accelerator.cc
+++ b/chromium/content/common/gpu/media/vaapi_video_encode_accelerator.cc
@@ -13,6 +13,7 @@
#include "base/metrics/histogram.h"
#include "base/numerics/safe_conversions.h"
#include "content/common/gpu/media/h264_dpb.h"
+#include "content/common/gpu/media/shared_memory_region.h"
#include "media/base/bind_to_current_loop.h"
#include "third_party/libva/va/va_enc_h264.h"
@@ -100,13 +101,10 @@ struct VaapiVideoEncodeAccelerator::InputFrameRef {
};
struct VaapiVideoEncodeAccelerator::BitstreamBufferRef {
- BitstreamBufferRef(int32_t id,
- scoped_ptr<base::SharedMemory> shm,
- size_t size)
- : id(id), shm(std::move(shm)), size(size) {}
+ BitstreamBufferRef(int32_t id, scoped_ptr<SharedMemoryRegion> shm)
+ : id(id), shm(std::move(shm)) {}
const int32_t id;
- const scoped_ptr<base::SharedMemory> shm;
- const size_t size;
+ const scoped_ptr<SharedMemoryRegion> shm;
};
media::VideoEncodeAccelerator::SupportedProfiles
@@ -176,9 +174,19 @@ bool VaapiVideoEncodeAccelerator::Initialize(
client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
client_ = client_ptr_factory_->GetWeakPtr();
- if (output_profile < media::H264PROFILE_BASELINE ||
- output_profile > media::H264PROFILE_MAIN) {
- DVLOGF(1) << "Unsupported output profile: " << output_profile;
+ const SupportedProfiles& profiles = GetSupportedProfiles();
+ auto profile = find_if(profiles.begin(), profiles.end(),
+ [output_profile](const SupportedProfile& profile) {
+ return profile.profile == output_profile;
+ });
+ if (profile == profiles.end()) {
+ DVLOGF(1) << "Unsupported output profile " << output_profile;
+ return false;
+ }
+ if (input_visible_size.width() > profile->max_resolution.width() ||
+ input_visible_size.height() > profile->max_resolution.height()) {
+ DVLOGF(1) << "Input size too big: " << input_visible_size.ToString()
+ << ", max supported size: " << profile->max_resolution.ToString();
return false;
}
@@ -546,11 +554,8 @@ void VaapiVideoEncodeAccelerator::TryToReturnBitstreamBuffer() {
size_t data_size = 0;
if (!vaapi_wrapper_->DownloadAndDestroyCodedBuffer(
- encode_job->coded_buffer,
- encode_job->input_surface->id(),
- target_data,
- buffer->size,
- &data_size)) {
+ encode_job->coded_buffer, encode_job->input_surface->id(),
+ target_data, buffer->shm->size(), &data_size)) {
NOTIFY_ERROR(kPlatformFailureError, "Failed downloading coded buffer");
return;
}
@@ -669,15 +674,14 @@ void VaapiVideoEncodeAccelerator::UseOutputBitstreamBuffer(
return;
}
- scoped_ptr<base::SharedMemory> shm(
- new base::SharedMemory(buffer.handle(), false));
- if (!shm->Map(buffer.size())) {
+ scoped_ptr<SharedMemoryRegion> shm(new SharedMemoryRegion(buffer, false));
+ if (!shm->Map()) {
NOTIFY_ERROR(kPlatformFailureError, "Failed mapping shared memory.");
return;
}
scoped_ptr<BitstreamBufferRef> buffer_ref(
- new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size()));
+ new BitstreamBufferRef(buffer.id(), std::move(shm)));
encoder_thread_task_runner_->PostTask(
FROM_HERE,
diff --git a/chromium/content/common/gpu/media/vaapi_wrapper.cc b/chromium/content/common/gpu/media/vaapi_wrapper.cc
index db38f32f7f8..19303e1e6d6 100644
--- a/chromium/content/common/gpu/media/vaapi_wrapper.cc
+++ b/chromium/content/common/gpu/media/vaapi_wrapper.cc
@@ -9,7 +9,6 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
@@ -18,7 +17,6 @@
// Auto-generated for dlopen libva libraries
#include "content/common/gpu/media/va_stubs.h"
#include "content/common/gpu/media/vaapi_picture.h"
-#include "content/public/common/content_switches.h"
#include "third_party/libyuv/include/libyuv.h"
#include "ui/gl/gl_bindings.h"
#if defined(USE_X11)
@@ -127,7 +125,9 @@ static const ProfileMap kProfileMap[] = {
// media::H264PROFILE_HIGH*.
{media::H264PROFILE_HIGH, VAProfileH264High},
{media::VP8PROFILE_ANY, VAProfileVP8Version0_3},
- {media::VP9PROFILE_ANY, VAProfileVP9Profile0},
+ // TODO(servolk): Need to add VP9 profiles 1,2,3 here after rolling
+ // third_party/libva to 1.7. crbug.com/598118
+ {media::VP9PROFILE_PROFILE0, VAProfileVP9Profile0},
};
static std::vector<VAConfigAttrib> GetRequiredAttribs(
@@ -214,10 +214,6 @@ scoped_refptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
media::VideoEncodeAccelerator::SupportedProfiles
VaapiWrapper::GetSupportedEncodeProfiles() {
media::VideoEncodeAccelerator::SupportedProfiles profiles;
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode))
- return profiles;
-
std::vector<ProfileInfo> encode_profile_infos =
profile_infos_.Get().GetSupportedProfileInfosForCodecMode(kEncode);
@@ -369,11 +365,8 @@ bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
return false;
}
- VAStatus va_res = VA_STATUS_SUCCESS;
- if (!va_display_state->Initialize(&va_res)) {
- VA_LOG_ON_ERROR(va_res, "vaInitialize failed");
+ if (!va_display_state->Initialize())
return false;
- }
va_display_ = va_display_state->va_display();
return true;
@@ -1218,7 +1211,7 @@ VaapiWrapper::VADisplayState::VADisplayState()
VaapiWrapper::VADisplayState::~VADisplayState() {}
-bool VaapiWrapper::VADisplayState::Initialize(VAStatus* status) {
+bool VaapiWrapper::VADisplayState::Initialize() {
va_lock_.AssertAcquired();
if (refcount_++ == 0) {
#if defined(USE_X11)
@@ -1232,9 +1225,12 @@ bool VaapiWrapper::VADisplayState::Initialize(VAStatus* status) {
return false;
}
- *status = vaInitialize(va_display_, &major_version_, &minor_version_);
- if (*status != VA_STATUS_SUCCESS)
+ VAStatus va_res =
+ vaInitialize(va_display_, &major_version_, &minor_version_);
+ if (va_res != VA_STATUS_SUCCESS) {
+ LOG(WARNING) << "vaInitialize failed: " << vaErrorStr(va_res);
return false;
+ }
va_initialized_ = true;
DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
diff --git a/chromium/content/common/gpu/media/vaapi_wrapper.h b/chromium/content/common/gpu/media/vaapi_wrapper.h
index 7f14b49be11..4394bc36b92 100644
--- a/chromium/content/common/gpu/media/vaapi_wrapper.h
+++ b/chromium/content/common/gpu/media/vaapi_wrapper.h
@@ -247,7 +247,7 @@ class CONTENT_EXPORT VaapiWrapper
~VADisplayState();
// |va_lock_| must be held on entry.
- bool Initialize(VAStatus* status);
+ bool Initialize();
void Deinitialize(VAStatus* status);
base::Lock* va_lock() { return &va_lock_; }
diff --git a/chromium/content/common/gpu/media/video_decode_accelerator_unittest.cc b/chromium/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 36466304a3c..91339668867 100644
--- a/chromium/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/chromium/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -47,9 +47,10 @@
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "content/common/gpu/media/fake_video_decode_accelerator.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h"
#include "content/common/gpu/media/rendering_helper.h"
#include "content/common/gpu/media/video_accelerator_unittest_helpers.h"
-#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
#include "media/filters/h264_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/codec/png_codec.h"
@@ -334,6 +335,7 @@ class GLRenderingVDAClient
// VideoDecodeAccelerator::Client implementation.
// The heart of the Client.
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
+ uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
void DismissPictureBuffer(int32_t picture_buffer_id) override;
@@ -359,16 +361,6 @@ class GLRenderingVDAClient
private:
typedef std::map<int32_t, scoped_refptr<TextureRef>> TextureRefMap;
- scoped_ptr<media::VideoDecodeAccelerator> CreateFakeVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SliceVDA();
- scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA();
-
- void BindImage(uint32_t client_texture_id,
- uint32_t texture_target,
- scoped_refptr<gl::GLImage> image);
-
void SetState(ClientState new_state);
void FinishInitialization();
void ReturnPicture(int32_t picture_buffer_id);
@@ -401,8 +393,10 @@ class GLRenderingVDAClient
int next_bitstream_buffer_id_;
ClientStateNotification<ClientState>* note_;
scoped_ptr<VideoDecodeAccelerator> decoder_;
- scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator> >
- weak_decoder_factory_;
+ base::WeakPtr<VideoDecodeAccelerator> weak_vda_;
+ scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator>>
+ weak_vda_ptr_factory_;
+ scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> vda_factory_;
int remaining_play_throughs_;
int reset_after_frame_num_;
int delete_decoder_state_;
@@ -440,9 +434,23 @@ class GLRenderingVDAClient
int32_t next_picture_buffer_id_;
+ base::WeakPtr<GLRenderingVDAClient> weak_this_;
+ base::WeakPtrFactory<GLRenderingVDAClient> weak_this_factory_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient);
};
+static bool DoNothingReturnTrue() {
+ return true;
+}
+
+static bool DummyBindImage(uint32_t client_texture_id,
+ uint32_t texture_target,
+ const scoped_refptr<gl::GLImage>& image,
+ bool can_bind_to_sampler) {
+ return true;
+}
+
GLRenderingVDAClient::GLRenderingVDAClient(
size_t window_id,
RenderingHelper* rendering_helper,
@@ -483,7 +491,8 @@ GLRenderingVDAClient::GLRenderingVDAClient(
delay_reuse_after_frame_num_(delay_reuse_after_frame_num),
decode_calls_per_second_(decode_calls_per_second),
render_as_thumbnails_(render_as_thumbnails),
- next_picture_buffer_id_(1) {
+ next_picture_buffer_id_(1),
+ weak_this_factory_(this) {
LOG_ASSERT(num_in_flight_decodes > 0);
LOG_ASSERT(num_play_throughs > 0);
// |num_in_flight_decodes_| is unsupported if |decode_calls_per_second_| > 0.
@@ -494,6 +503,8 @@ GLRenderingVDAClient::GLRenderingVDAClient(
profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN
? profile
: media::H264PROFILE_BASELINE);
+
+ weak_this_ = weak_this_factory_.GetWeakPtr();
}
GLRenderingVDAClient::~GLRenderingVDAClient() {
@@ -502,119 +513,49 @@ GLRenderingVDAClient::~GLRenderingVDAClient() {
SetState(CS_DESTROYED);
}
-static bool DoNothingReturnTrue() { return true; }
+void GLRenderingVDAClient::CreateAndStartDecoder() {
+ LOG_ASSERT(decoder_deleted());
+ LOG_ASSERT(!decoder_.get());
-scoped_ptr<media::VideoDecodeAccelerator>
-GLRenderingVDAClient::CreateFakeVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
if (fake_decoder_) {
- decoder.reset(new FakeVideoDecodeAccelerator(
- static_cast<gfx::GLContext*> (rendering_helper_->GetGLContextHandle()),
- frame_size_,
- base::Bind(&DoNothingReturnTrue)));
- }
- return decoder;
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GLRenderingVDAClient::CreateDXVAVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_WIN)
- if (base::win::GetVersion() >= base::win::VERSION_WIN7)
- decoder.reset(
- new DXVAVideoDecodeAccelerator(
- base::Bind(&DoNothingReturnTrue),
- rendering_helper_->GetGLContext().get()));
-#endif
- return decoder;
-}
-
-scoped_ptr<media::VideoDecodeAccelerator>
-GLRenderingVDAClient::CreateV4L2VDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
- if (device.get()) {
- base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr();
- decoder.reset(new V4L2VideoDecodeAccelerator(
- static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
- static_cast<EGLContext>(rendering_helper_->GetGLContextHandle()),
- weak_client, base::Bind(&DoNothingReturnTrue), device,
- base::ThreadTaskRunnerHandle::Get()));
- }
-#endif
- return decoder;
-}
+ decoder_.reset(new FakeVideoDecodeAccelerator(
+ frame_size_, base::Bind(&DoNothingReturnTrue)));
+ LOG_ASSERT(decoder_->Initialize(profile_, this));
+ } else {
+ if (!vda_factory_) {
+ vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create(
+ base::Bind(&RenderingHelper::GetGLContext,
+ base::Unretained(rendering_helper_)),
+ base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage));
+ LOG_ASSERT(vda_factory_);
+ }
-scoped_ptr<media::VideoDecodeAccelerator>
-GLRenderingVDAClient::CreateV4L2SliceVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
- if (device.get()) {
- base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr();
- decoder.reset(new V4L2SliceVideoDecodeAccelerator(
- device, static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
- static_cast<EGLContext>(rendering_helper_->GetGLContextHandle()),
- weak_client, base::Bind(&DoNothingReturnTrue),
- base::ThreadTaskRunnerHandle::Get()));
+ VideoDecodeAccelerator::Config config(profile_);
+ gpu::GpuPreferences gpu_preferences;
+ decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences);
}
-#endif
- return decoder;
-}
-scoped_ptr<media::VideoDecodeAccelerator>
-GLRenderingVDAClient::CreateVaapiVDA() {
- scoped_ptr<media::VideoDecodeAccelerator> decoder;
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
- decoder.reset(new VaapiVideoDecodeAccelerator(
- base::Bind(&DoNothingReturnTrue),
- base::Bind(&GLRenderingVDAClient::BindImage, base::Unretained(this))));
-#endif
- return decoder;
-}
+ LOG_ASSERT(decoder_) << "Failed creating a VDA";
-void GLRenderingVDAClient::BindImage(uint32_t client_texture_id,
- uint32_t texture_target,
- scoped_refptr<gl::GLImage> image) {}
+ decoder_->TryToSetupDecodeOnSeparateThread(
+ weak_this_, base::ThreadTaskRunnerHandle::Get());
-void GLRenderingVDAClient::CreateAndStartDecoder() {
- LOG_ASSERT(decoder_deleted());
- LOG_ASSERT(!decoder_.get());
-
- VideoDecodeAccelerator::Client* client = this;
-
- scoped_ptr<media::VideoDecodeAccelerator> decoders[] = {
- CreateFakeVDA(),
- CreateDXVAVDA(),
- CreateV4L2VDA(),
- CreateV4L2SliceVDA(),
- CreateVaapiVDA(),
- };
+ weak_vda_ptr_factory_.reset(
+ new base::WeakPtrFactory<VideoDecodeAccelerator>(decoder_.get()));
+ weak_vda_ = weak_vda_ptr_factory_->GetWeakPtr();
- for (size_t i = 0; i < arraysize(decoders); ++i) {
- if (!decoders[i])
- continue;
- decoder_ = std::move(decoders[i]);
- weak_decoder_factory_.reset(
- new base::WeakPtrFactory<VideoDecodeAccelerator>(decoder_.get()));
- if (decoder_->Initialize(profile_, client)) {
- SetState(CS_DECODER_SET);
- FinishInitialization();
- return;
- }
- }
- // Decoders are all initialize failed.
- LOG(ERROR) << "VideoDecodeAccelerator::Initialize() failed";
- LOG_ASSERT(false);
+ SetState(CS_DECODER_SET);
+ FinishInitialization();
}
void GLRenderingVDAClient::ProvidePictureBuffers(
uint32_t requested_num_of_buffers,
+ uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) {
if (decoder_deleted())
return;
+ LOG_ASSERT(textures_per_buffer == 1u);
std::vector<media::PictureBuffer> buffers;
requested_num_of_buffers += kExtraPictureBuffers;
@@ -637,8 +578,9 @@ void GLRenderingVDAClient::ProvidePictureBuffers(
texture_id))))
.second);
- buffers.push_back(
- media::PictureBuffer(picture_buffer_id, dimensions, texture_id));
+ media::PictureBuffer::TextureIds ids;
+ ids.push_back(texture_id);
+ buffers.push_back(media::PictureBuffer(picture_buffer_id, dimensions, ids));
}
decoder_->AssignPictureBuffers(buffers);
}
@@ -710,10 +652,8 @@ void GLRenderingVDAClient::ReturnPicture(int32_t picture_buffer_id) {
if (num_decoded_frames_ > delay_reuse_after_frame_num_) {
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer,
- weak_decoder_factory_->GetWeakPtr(),
- picture_buffer_id),
+ FROM_HERE, base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer,
+ weak_vda_, picture_buffer_id),
kReuseDelay);
} else {
decoder_->ReusePictureBuffer(picture_buffer_id);
@@ -835,7 +775,7 @@ void GLRenderingVDAClient::FinishInitialization() {
void GLRenderingVDAClient::DeleteDecoder() {
if (decoder_deleted())
return;
- weak_decoder_factory_.reset();
+ weak_vda_ptr_factory_->InvalidateWeakPtrs();
decoder_.reset();
STLClearObject(&encoded_data_);
active_textures_.clear();
@@ -1196,17 +1136,6 @@ class VideoDecodeAcceleratorParamTest
base::Tuple<int, int, int, ResetPoint, ClientState, bool, bool> > {
};
-// Helper so that gtest failures emit a more readable version of the tuple than
-// its byte representation.
-::std::ostream& operator<<(
- ::std::ostream& os,
- const base::Tuple<int, int, int, ResetPoint, ClientState, bool, bool>& t) {
- return os << base::get<0>(t) << ", " << base::get<1>(t) << ", "
- << base::get<2>(t) << ", " << base::get<3>(t) << ", "
- << base::get<4>(t) << ", " << base::get<5>(t) << ", "
- << base::get<6>(t);
-}
-
// Wait for |note| to report a state and if it's not |expected_state| then
// assert |client| has deleted its decoder.
static void AssertWaitForStateOrDeleted(
diff --git a/chromium/content/common/gpu/media/video_encode_accelerator_unittest.cc b/chromium/content/common/gpu/media/video_encode_accelerator_unittest.cc
index 9224e89c72f..09f1c63ed23 100644
--- a/chromium/content/common/gpu/media/video_encode_accelerator_unittest.cc
+++ b/chromium/content/common/gpu/media/video_encode_accelerator_unittest.cc
@@ -55,6 +55,8 @@
// Status has been defined as int in Xlib.h.
#undef Status
#endif // defined(ARCH_CPU_X86_FAMILY)
+#elif defined(OS_MACOSX)
+#include "content/common/gpu/media/vt_video_encode_accelerator_mac.h"
#else
#error The VideoEncodeAcceleratorUnittest is not supported on this platform.
#endif
@@ -126,7 +128,11 @@ const unsigned int kLoggedLatencyPercentiles[] = {50, 75, 95};
// of the stream.
// Bitrate is only forced for tests that test bitrate.
const char* g_default_in_filename = "bear_320x192_40frames.yuv";
+#if !defined(OS_MACOSX)
const char* g_default_in_parameters = ":320:192:1:out.h264:200000";
+#else
+const char* g_default_in_parameters = ":320:192:0:out.h264:200000";
+#endif
// Enabled by including a --fake_encoder flag to the command line invoking the
// test.
@@ -623,8 +629,8 @@ class VideoFrameQualityValidator {
private:
void InitializeCB(bool success);
- void DecodeDone(media::VideoDecoder::Status status);
- void FlushDone(media::VideoDecoder::Status status);
+ void DecodeDone(media::DecodeStatus status);
+ void FlushDone(media::DecodeStatus status);
void VerifyOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame);
void Decode();
@@ -670,16 +676,18 @@ void VideoFrameQualityValidator::Initialize(const gfx::Size& coded_size,
if (IsVP8(profile_))
config.Initialize(media::kCodecVP8, media::VP8PROFILE_ANY, kInputFormat,
media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size,
- natural_size, media::EmptyExtraData(), false);
+ natural_size, media::EmptyExtraData(),
+ media::Unencrypted());
else if (IsH264(profile_))
config.Initialize(media::kCodecH264, media::H264PROFILE_MAIN, kInputFormat,
media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size,
- natural_size, media::EmptyExtraData(), false);
+ natural_size, media::EmptyExtraData(),
+ media::Unencrypted());
else
LOG_ASSERT(0) << "Invalid profile " << profile_;
decoder_->Initialize(
- config, false, media::SetCdmReadyCB(),
+ config, false, nullptr,
base::Bind(&VideoFrameQualityValidator::InitializeCB,
base::Unretained(this)),
base::Bind(&VideoFrameQualityValidator::VerifyOutputFrame,
@@ -704,9 +712,8 @@ void VideoFrameQualityValidator::AddOriginalFrame(
original_frames_.push(frame);
}
-void VideoFrameQualityValidator::DecodeDone(
- media::VideoDecoder::Status status) {
- if (status == media::VideoDecoder::kOk) {
+void VideoFrameQualityValidator::DecodeDone(media::DecodeStatus status) {
+ if (status == media::DecodeStatus::OK) {
decoder_state_ = INITIALIZED;
Decode();
} else {
@@ -716,7 +723,7 @@ void VideoFrameQualityValidator::DecodeDone(
}
}
-void VideoFrameQualityValidator::FlushDone(media::VideoDecoder::Status status) {
+void VideoFrameQualityValidator::FlushDone(media::DecodeStatus status) {
flush_complete_cb_.Run();
}
@@ -810,6 +817,7 @@ class VEAClient : public VideoEncodeAccelerator::Client {
scoped_ptr<media::VideoEncodeAccelerator> CreateFakeVEA();
scoped_ptr<media::VideoEncodeAccelerator> CreateV4L2VEA();
scoped_ptr<media::VideoEncodeAccelerator> CreateVaapiVEA();
+ scoped_ptr<media::VideoEncodeAccelerator> CreateVTVEA();
void SetState(ClientState new_state);
@@ -1071,6 +1079,14 @@ scoped_ptr<media::VideoEncodeAccelerator> VEAClient::CreateVaapiVEA() {
return encoder;
}
+scoped_ptr<media::VideoEncodeAccelerator> VEAClient::CreateVTVEA() {
+ scoped_ptr<media::VideoEncodeAccelerator> encoder;
+#if defined(OS_MACOSX)
+ encoder.reset(new VTVideoEncodeAccelerator());
+#endif
+ return encoder;
+}
+
void VEAClient::CreateEncoder() {
DCHECK(thread_checker_.CalledOnValidThread());
LOG_ASSERT(!has_encoder());
@@ -1078,7 +1094,8 @@ void VEAClient::CreateEncoder() {
scoped_ptr<media::VideoEncodeAccelerator> encoders[] = {
CreateFakeVEA(),
CreateV4L2VEA(),
- CreateVaapiVEA()
+ CreateVaapiVEA(),
+ CreateVTVEA()
};
DVLOG(1) << "Profile: " << test_stream_->requested_profile
@@ -1649,6 +1666,7 @@ TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) {
encoder_thread.Stop();
}
+#if !defined(OS_MACOSX)
INSTANTIATE_TEST_CASE_P(
SimpleEncode,
VideoEncodeAcceleratorTest,
@@ -1693,6 +1711,26 @@ INSTANTIATE_TEST_CASE_P(
base::MakeTuple(3, false, 0, false, false, false, false, false),
base::MakeTuple(3, false, 0, true, false, false, true, false),
base::MakeTuple(3, false, 0, true, false, true, false, false)));
+#else
+INSTANTIATE_TEST_CASE_P(
+ SimpleEncode,
+ VideoEncodeAcceleratorTest,
+ ::testing::Values(
+ base::MakeTuple(1, true, 0, false, false, false, false, false),
+ base::MakeTuple(1, true, 0, false, false, false, false, true)));
+
+INSTANTIATE_TEST_CASE_P(
+ EncoderPerf,
+ VideoEncodeAcceleratorTest,
+ ::testing::Values(
+ base::MakeTuple(1, false, 0, false, true, false, false, false)));
+
+INSTANTIATE_TEST_CASE_P(
+ MultipleEncoders,
+ VideoEncodeAcceleratorTest,
+ ::testing::Values(
+ base::MakeTuple(3, false, 0, false, false, false, false, false)));
+#endif
// TODO(posciak): more tests:
// - async FeedEncoderWithOutput
diff --git a/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.cc b/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
index e74e6f64d55..1571e834620 100644
--- a/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
+++ b/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
@@ -10,7 +10,6 @@
#include <stddef.h>
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/macros.h"
@@ -20,7 +19,6 @@
#include "base/thread_task_runner_handle.h"
#include "base/version.h"
#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h"
-#include "content/public/common/content_switches.h"
#include "media/base/limits.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image_io_surface.h"
@@ -46,7 +44,11 @@ static const media::VideoCodecProfile kSupportedProfiles[] = {
media::H264PROFILE_MAIN,
media::H264PROFILE_EXTENDED,
media::H264PROFILE_HIGH,
- media::H264PROFILE_HIGH10PROFILE,
+ // TODO(hubbe): Try to re-enable this again somehow. Currently it seems
+ // that some codecs fail to check the profile during initialization and
+ // then fail on the first frame decode, which currently results in a
+ // pipeline failure.
+ // media::H264PROFILE_HIGH10PROFILE,
media::H264PROFILE_SCALABLEBASELINE,
media::H264PROFILE_SCALABLEHIGH,
media::H264PROFILE_STEREOHIGH,
@@ -72,9 +74,9 @@ static base::ScopedCFTypeRef<CFMutableDictionaryRef>
BuildImageConfig(CMVideoDimensions coded_dimensions) {
base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
- // 4:2:2 is used over the native 4:2:0 because only 4:2:2 can be directly
- // bound to a texture by CGLTexImageIOSurface2D().
- int32_t pixel_format = kCVPixelFormatType_422YpCbCr8;
+ // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are
+ // lower power than 4:2:2 when composited directly by CoreAnimation.
+ int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
#define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i)
base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format));
base::ScopedCFTypeRef<CFNumberRef> cf_width(CFINT(coded_dimensions.width));
@@ -86,7 +88,7 @@ BuildImageConfig(CMVideoDimensions coded_dimensions) {
image_config.reset(
CFDictionaryCreateMutable(
kCFAllocatorDefault,
- 4, // capacity
+ 3, // capacity
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
if (!image_config.get())
@@ -96,8 +98,6 @@ BuildImageConfig(CMVideoDimensions coded_dimensions) {
cf_pixel_format);
CFDictionarySetValue(image_config, kCVPixelBufferWidthKey, cf_width);
CFDictionarySetValue(image_config, kCVPixelBufferHeightKey, cf_height);
- CFDictionarySetValue(image_config, kCVPixelBufferOpenGLCompatibilityKey,
- kCFBooleanTrue);
return image_config;
}
@@ -175,11 +175,6 @@ static bool CreateVideoToolboxSession(const uint8_t* sps, size_t sps_size,
// session fails, hardware decoding will be disabled (Initialize() will always
// return false).
static bool InitializeVideoToolboxInternal() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableAcceleratedVideoDecode)) {
- return false;
- }
-
if (!IsVtInitialized()) {
// CoreVideo is also required, but the loader stops after the first path is
// loaded. Instead we rely on the transitive dependency from VideoToolbox to
@@ -255,6 +250,8 @@ static void OutputThunk(
VTVideoDecodeAccelerator::Task::Task(TaskType type) : type(type) {
}
+VTVideoDecodeAccelerator::Task::Task(const Task& other) = default;
+
VTVideoDecodeAccelerator::Task::~Task() {
}
@@ -291,11 +288,10 @@ bool VTVideoDecodeAccelerator::FrameOrder::operator()(
}
VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>&
- bind_image)
- : make_context_current_(make_context_current),
- bind_image_(bind_image),
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb)
+ : make_context_current_cb_(make_context_current_cb),
+ bind_image_cb_(bind_image_cb),
client_(nullptr),
state_(STATE_DECODING),
format_(nullptr),
@@ -307,7 +303,6 @@ VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(
gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()),
decoder_thread_("VTDecoderThread"),
weak_this_factory_(this) {
- DCHECK(!make_context_current_.is_null());
callback_.decompressionOutputCallback = OutputThunk;
callback_.decompressionOutputRefCon = this;
weak_this_ = weak_this_factory_.GetWeakPtr();
@@ -321,6 +316,11 @@ bool VTVideoDecodeAccelerator::Initialize(const Config& config,
Client* client) {
DCHECK(gpu_thread_checker_.CalledOnValidThread());
+ if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) {
+ NOTREACHED() << "GL callbacks are required for this VDA";
+ return false;
+ }
+
if (config.is_encrypted) {
NOTREACHED() << "Encrypted streams are not supported for this VDA";
return false;
@@ -622,23 +622,21 @@ void VTVideoDecodeAccelerator::DecodeTask(
config_changed_ = true;
}
if (config_changed_) {
- if (last_sps_.empty()) {
- config_changed_ = false;
- DLOG(ERROR) << "Invalid configuration; no SPS";
- NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
- return;
- }
- if (last_pps_.empty()) {
- config_changed_ = false;
- DLOG(ERROR) << "Invalid configuration; no PPS";
- NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
- return;
- }
-
// Only reconfigure at IDRs to avoid corruption.
if (frame->is_idr) {
config_changed_ = false;
+ if (last_sps_.empty()) {
+ DLOG(ERROR) << "Invalid configuration; no SPS";
+ NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
+ return;
+ }
+ if (last_pps_.empty()) {
+ DLOG(ERROR) << "Invalid configuration; no PPS";
+ NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
+ return;
+ }
+
// ConfigureDecoder() calls NotifyError() on failure.
if (!ConfigureDecoder())
return;
@@ -825,6 +823,13 @@ void VTVideoDecodeAccelerator::FlushDone(TaskType type) {
void VTVideoDecodeAccelerator::Decode(const media::BitstreamBuffer& bitstream) {
DCHECK(gpu_thread_checker_.CalledOnValidThread());
+ if (bitstream.id() < 0) {
+ DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id();
+ if (base::SharedMemory::IsHandleValid(bitstream.handle()))
+ base::SharedMemory::CloseHandle(bitstream.handle());
+ NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
+ return;
+ }
DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id()));
assigned_bitstream_ids_.insert(bitstream.id());
Frame* frame = new Frame(bitstream.id());
@@ -842,10 +847,12 @@ void VTVideoDecodeAccelerator::AssignPictureBuffers(
DCHECK(!picture_info_map_.count(picture.id()));
assigned_picture_ids_.insert(picture.id());
available_picture_ids_.push_back(picture.id());
+ DCHECK_LE(1u, picture.internal_texture_ids().size());
+ DCHECK_LE(1u, picture.texture_ids().size());
picture_info_map_.insert(std::make_pair(
picture.id(),
- make_scoped_ptr(new PictureInfo(picture.internal_texture_id(),
- picture.texture_id()))));
+ make_scoped_ptr(new PictureInfo(picture.internal_texture_ids()[0],
+ picture.texture_ids()[0]))));
}
// Pictures are not marked as uncleared until after this method returns, and
@@ -859,7 +866,7 @@ void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
DCHECK(gpu_thread_checker_.CalledOnValidThread());
DCHECK(picture_info_map_.count(picture_id));
PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get();
- DCHECK_EQ(CFGetRetainCount(picture_info->cv_image), 1);
+ DCHECK_EQ(CFGetRetainCount(picture_info->cv_image), 2);
picture_info->cv_image.reset();
picture_info->gl_image->Destroy(false);
picture_info->gl_image = nullptr;
@@ -1002,8 +1009,8 @@ bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) {
// Request new pictures.
picture_size_ = frame.coded_size;
- client_->ProvidePictureBuffers(
- kNumPictureBuffers, coded_size_, GL_TEXTURE_RECTANGLE_ARB);
+ client_->ProvidePictureBuffers(kNumPictureBuffers, 1, coded_size_,
+ GL_TEXTURE_RECTANGLE_ARB);
return false;
}
if (!SendFrame(frame))
@@ -1026,47 +1033,27 @@ bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) {
DCHECK(!picture_info->cv_image);
DCHECK(!picture_info->gl_image);
- if (!make_context_current_.Run()) {
+ if (!make_context_current_cb_.Run()) {
DLOG(ERROR) << "Failed to make GL context current";
NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
return false;
}
- IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image.get());
- if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile)
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_RECTANGLE_ARB,
- picture_info->service_texture_id);
- CGLContextObj cgl_context =
- static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle());
- CGLError status = CGLTexImageIOSurface2D(
- cgl_context, // ctx
- GL_TEXTURE_RECTANGLE_ARB, // target
- GL_RGB, // internal_format
- frame.coded_size.width(), // width
- frame.coded_size.height(), // height
- GL_YCBCR_422_APPLE, // format
- GL_UNSIGNED_SHORT_8_8_APPLE, // type
- surface, // io_surface
- 0); // plane
- if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile)
- glDisable(GL_TEXTURE_RECTANGLE_ARB);
- if (status != kCGLNoError) {
- NOTIFY_STATUS("CGLTexImageIOSurface2D()", status, SFT_PLATFORM_ERROR);
- return false;
- }
-
- bool allow_overlay = false;
scoped_refptr<gl::GLImageIOSurface> gl_image(
new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT));
- if (gl_image->Initialize(surface, gfx::GenericSharedMemoryId(),
- gfx::BufferFormat::BGRA_8888)) {
- allow_overlay = true;
- } else {
- gl_image = nullptr;
+ if (!gl_image->InitializeWithCVPixelBuffer(
+ frame.image.get(), gfx::GenericSharedMemoryId(),
+ gfx::BufferFormat::YUV_420_BIPLANAR)) {
+ NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE,
+ SFT_PLATFORM_ERROR);
+ }
+
+ if (!bind_image_cb_.Run(picture_info->client_texture_id,
+ GL_TEXTURE_RECTANGLE_ARB, gl_image, false)) {
+ DLOG(ERROR) << "Failed to bind image";
+ NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
+ return false;
}
- bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB,
- gl_image);
// Assign the new image(s) to the the picture info.
picture_info->gl_image = gl_image;
@@ -1080,7 +1067,7 @@ bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) {
// coded size and fix it.
client_->PictureReady(media::Picture(picture_id, frame.bitstream_id,
gfx::Rect(frame.coded_size),
- allow_overlay));
+ true));
return true;
}
@@ -1143,7 +1130,9 @@ void VTVideoDecodeAccelerator::Destroy() {
QueueFlush(TASK_DESTROY);
}
-bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() {
+bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
return false;
}
diff --git a/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.h b/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.h
index 2d222163823..22fc8b1d6ad 100644
--- a/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.h
+++ b/chromium/content/common/gpu/media/vt_video_decode_accelerator_mac.h
@@ -17,6 +17,7 @@
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
+#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
#include "content/common/gpu/media/vt_mac.h"
#include "media/filters/h264_parser.h"
#include "media/video/h264_poc.h"
@@ -35,9 +36,9 @@ bool InitializeVideoToolbox();
class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
public:
explicit VTVideoDecodeAccelerator(
- const base::Callback<bool(void)>& make_context_current,
- const base::Callback<
- void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& bind_image);
+ const MakeGLContextCurrentCallback& make_context_current_cb,
+ const BindGLImageCallback& bind_image_cb);
+
~VTVideoDecodeAccelerator() override;
// VideoDecodeAccelerator implementation.
@@ -49,7 +50,10 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
void Flush() override;
void Reset() override;
void Destroy() override;
- bool CanDecodeOnIOThread() override;
+ bool TryToSetupDecodeOnSeparateThread(
+ const base::WeakPtr<Client>& decode_client,
+ const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
+ override;
// Called by OutputThunk() when VideoToolbox finishes decoding a frame.
void Output(
@@ -114,6 +118,7 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
struct Task {
Task(TaskType type);
+ Task(const Task& other);
~Task();
TaskType type;
@@ -189,9 +194,9 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
//
// GPU thread state.
//
- base::Callback<bool(void)> make_context_current_;
- base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>
- bind_image_;
+ MakeGLContextCurrentCallback make_context_current_cb_;
+ BindGLImageCallback bind_image_cb_;
+
media::VideoDecodeAccelerator::Client* client_;
State state_;
diff --git a/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.cc b/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.cc
new file mode 100644
index 00000000000..71c80ef3a9f
--- /dev/null
+++ b/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.cc
@@ -0,0 +1,552 @@
+// Copyright 2016 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 "content/common/gpu/media/vt_video_encode_accelerator_mac.h"
+
+#include "base/thread_task_runner_handle.h"
+#include "media/base/mac/coremedia_glue.h"
+#include "media/base/mac/corevideo_glue.h"
+#include "media/base/mac/video_frame_mac.h"
+
+namespace content {
+
+namespace {
+
+// TODO(emircan): Check if we can find the actual system capabilities via
+// creating VTCompressionSessions with varying requirements.
+// See crbug.com/584784.
+const size_t kBitsPerByte = 8;
+const size_t kDefaultResolutionWidth = 640;
+const size_t kDefaultResolutionHeight = 480;
+const size_t kMaxFrameRateNumerator = 30;
+const size_t kMaxFrameRateDenominator = 1;
+const size_t kMaxResolutionWidth = 4096;
+const size_t kMaxResolutionHeight = 2160;
+const size_t kNumInputBuffers = 3;
+
+} // namespace
+
+struct VTVideoEncodeAccelerator::InProgressFrameEncode {
+ InProgressFrameEncode(base::TimeDelta rtp_timestamp,
+ base::TimeTicks ref_time)
+ : timestamp(rtp_timestamp), reference_time(ref_time) {}
+ const base::TimeDelta timestamp;
+ const base::TimeTicks reference_time;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(InProgressFrameEncode);
+};
+
+struct VTVideoEncodeAccelerator::EncodeOutput {
+ EncodeOutput(VTEncodeInfoFlags info_flags, CMSampleBufferRef sbuf)
+ : info(info_flags), sample_buffer(sbuf, base::scoped_policy::RETAIN) {}
+ const VTEncodeInfoFlags info;
+ const base::ScopedCFTypeRef<CMSampleBufferRef> sample_buffer;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(EncodeOutput);
+};
+
+struct VTVideoEncodeAccelerator::BitstreamBufferRef {
+ BitstreamBufferRef(int32_t id,
+ scoped_ptr<base::SharedMemory> shm,
+ size_t size)
+ : id(id), shm(std::move(shm)), size(size) {}
+ const int32_t id;
+ const scoped_ptr<base::SharedMemory> shm;
+ const size_t size;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBufferRef);
+};
+
+VTVideoEncodeAccelerator::VTVideoEncodeAccelerator()
+ : client_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ encoder_thread_("VTEncoderThread"),
+ encoder_task_weak_factory_(this) {
+ encoder_weak_ptr_ = encoder_task_weak_factory_.GetWeakPtr();
+}
+
+VTVideoEncodeAccelerator::~VTVideoEncodeAccelerator() {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ Destroy();
+ DCHECK(!encoder_thread_.IsRunning());
+ DCHECK(!encoder_task_weak_factory_.HasWeakPtrs());
+}
+
+media::VideoEncodeAccelerator::SupportedProfiles
+VTVideoEncodeAccelerator::GetSupportedProfiles() {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ SupportedProfiles profiles;
+ // Check if HW encoder is supported initially.
+ videotoolbox_glue_ = VideoToolboxGlue::Get();
+ if (!videotoolbox_glue_) {
+ DLOG(ERROR) << "Failed creating VideoToolbox glue.";
+ return profiles;
+ }
+ const bool rv = CreateCompressionSession(
+ media::video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0),
+ gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight), true);
+ DestroyCompressionSession();
+ if (!rv) {
+ VLOG(1)
+ << "Hardware encode acceleration is not available on this platform.";
+ return profiles;
+ }
+
+ SupportedProfile profile;
+ profile.profile = media::H264PROFILE_BASELINE;
+ profile.max_framerate_numerator = kMaxFrameRateNumerator;
+ profile.max_framerate_denominator = kMaxFrameRateDenominator;
+ profile.max_resolution = gfx::Size(kMaxResolutionWidth, kMaxResolutionHeight);
+ profiles.push_back(profile);
+ return profiles;
+}
+
+bool VTVideoEncodeAccelerator::Initialize(
+ media::VideoPixelFormat format,
+ const gfx::Size& input_visible_size,
+ media::VideoCodecProfile output_profile,
+ uint32_t initial_bitrate,
+ Client* client) {
+ DVLOG(3) << __FUNCTION__
+ << ": input_format=" << media::VideoPixelFormatToString(format)
+ << ", input_visible_size=" << input_visible_size.ToString()
+ << ", output_profile=" << output_profile
+ << ", initial_bitrate=" << initial_bitrate;
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(client);
+
+ if (media::PIXEL_FORMAT_I420 != format) {
+ DLOG(ERROR) << "Input format not supported= "
+ << media::VideoPixelFormatToString(format);
+ return false;
+ }
+ if (media::H264PROFILE_BASELINE != output_profile) {
+ DLOG(ERROR) << "Output profile not supported= "
+ << output_profile;
+ return false;
+ }
+
+ videotoolbox_glue_ = VideoToolboxGlue::Get();
+ if (!videotoolbox_glue_) {
+ DLOG(ERROR) << "Failed creating VideoToolbox glue.";
+ return false;
+ }
+
+ client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
+ client_ = client_ptr_factory_->GetWeakPtr();
+ input_visible_size_ = input_visible_size;
+ frame_rate_ = kMaxFrameRateNumerator / kMaxFrameRateDenominator;
+ target_bitrate_ = initial_bitrate;
+ bitstream_buffer_size_ = input_visible_size.GetArea();
+
+ if (!encoder_thread_.Start()) {
+ DLOG(ERROR) << "Failed spawning encoder thread.";
+ return false;
+ }
+ encoder_thread_task_runner_ = encoder_thread_.task_runner();
+
+ if (!ResetCompressionSession()) {
+ DLOG(ERROR) << "Failed creating compression session.";
+ return false;
+ }
+
+ client_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Client::RequireBitstreamBuffers, client_, kNumInputBuffers,
+ input_visible_size_, bitstream_buffer_size_));
+ return true;
+}
+
+void VTVideoEncodeAccelerator::Encode(
+ const scoped_refptr<media::VideoFrame>& frame,
+ bool force_keyframe) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ encoder_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VTVideoEncodeAccelerator::EncodeTask,
+ base::Unretained(this), frame, force_keyframe));
+}
+
+void VTVideoEncodeAccelerator::UseOutputBitstreamBuffer(
+ const media::BitstreamBuffer& buffer) {
+ DVLOG(3) << __FUNCTION__ << ": buffer size=" << buffer.size();
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (buffer.size() < bitstream_buffer_size_) {
+ DLOG(ERROR) << "Output BitstreamBuffer isn't big enough: " << buffer.size()
+ << " vs. " << bitstream_buffer_size_;
+ client_->NotifyError(kInvalidArgumentError);
+ return;
+ }
+
+ scoped_ptr<base::SharedMemory> shm(
+ new base::SharedMemory(buffer.handle(), false));
+ if (!shm->Map(buffer.size())) {
+ DLOG(ERROR) << "Failed mapping shared memory.";
+ client_->NotifyError(kPlatformFailureError);
+ return;
+ }
+
+ scoped_ptr<BitstreamBufferRef> buffer_ref(
+ new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size()));
+
+ encoder_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VTVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
+ base::Unretained(this), base::Passed(&buffer_ref)));
+}
+
+void VTVideoEncodeAccelerator::RequestEncodingParametersChange(
+ uint32_t bitrate,
+ uint32_t framerate) {
+ DVLOG(3) << __FUNCTION__ << ": bitrate=" << bitrate
+ << ": framerate=" << framerate;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ encoder_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VTVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
+ base::Unretained(this), bitrate, framerate));
+}
+
+void VTVideoEncodeAccelerator::Destroy() {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Cancel all callbacks.
+ client_ptr_factory_.reset();
+
+ if (encoder_thread_.IsRunning()) {
+ encoder_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VTVideoEncodeAccelerator::DestroyTask,
+ base::Unretained(this)));
+ encoder_thread_.Stop();
+ } else {
+ DestroyTask();
+ }
+}
+
+void VTVideoEncodeAccelerator::EncodeTask(
+ const scoped_refptr<media::VideoFrame>& frame,
+ bool force_keyframe) {
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+ DCHECK(compression_session_);
+ DCHECK(frame);
+
+ // TODO(emircan): See if we can eliminate a copy here by using
+ // CVPixelBufferPool for the allocation of incoming VideoFrames.
+ base::ScopedCFTypeRef<CVPixelBufferRef> pixel_buffer =
+ media::WrapVideoFrameInCVPixelBuffer(*frame);
+ base::ScopedCFTypeRef<CFDictionaryRef> frame_props =
+ media::video_toolbox::DictionaryWithKeyValue(
+ videotoolbox_glue_->kVTEncodeFrameOptionKey_ForceKeyFrame(),
+ force_keyframe ? kCFBooleanTrue : kCFBooleanFalse);
+
+ base::TimeTicks ref_time;
+ if (!frame->metadata()->GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &ref_time)) {
+ ref_time = base::TimeTicks::Now();
+ }
+ auto timestamp_cm = CoreMediaGlue::CMTimeMake(
+ frame->timestamp().InMicroseconds(), USEC_PER_SEC);
+ // Wrap information we'll need after the frame is encoded in a heap object.
+ // We'll get the pointer back from the VideoToolbox completion callback.
+ scoped_ptr<InProgressFrameEncode> request(new InProgressFrameEncode(
+ frame->timestamp(), ref_time));
+
+ // We can pass the ownership of |request| to the encode callback if
+ // successful. Otherwise let it fall out of scope.
+ OSStatus status = videotoolbox_glue_->VTCompressionSessionEncodeFrame(
+ compression_session_, pixel_buffer, timestamp_cm,
+ CoreMediaGlue::CMTime{0, 0, 0, 0}, frame_props,
+ reinterpret_cast<void*>(request.get()), nullptr);
+ if (status != noErr) {
+ DLOG(ERROR) << " VTCompressionSessionEncodeFrame failed: " << status;
+ NotifyError(kPlatformFailureError);
+ } else {
+ CHECK(request.release());
+ }
+}
+
+void VTVideoEncodeAccelerator::UseOutputBitstreamBufferTask(
+ scoped_ptr<BitstreamBufferRef> buffer_ref) {
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+
+ // If there is already EncodeOutput waiting, copy its output first.
+ if (!encoder_output_queue_.empty()) {
+ scoped_ptr<VTVideoEncodeAccelerator::EncodeOutput> encode_output =
+ std::move(encoder_output_queue_.front());
+ encoder_output_queue_.pop_front();
+ ReturnBitstreamBuffer(std::move(encode_output), std::move(buffer_ref));
+ return;
+ }
+
+ bitstream_buffer_queue_.push_back(std::move(buffer_ref));
+}
+
+void VTVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
+ uint32_t bitrate,
+ uint32_t framerate) {
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+
+ frame_rate_ = framerate > 1 ? framerate : 1;
+ target_bitrate_ = bitrate > 1 ? bitrate : 1;
+
+ if (!compression_session_) {
+ NotifyError(kPlatformFailureError);
+ return;
+ }
+
+ media::video_toolbox::SessionPropertySetter session_property_setter(
+ compression_session_, videotoolbox_glue_);
+ // TODO(emircan): See crbug.com/425352.
+ bool rv = session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_AverageBitRate(),
+ target_bitrate_);
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_ExpectedFrameRate(),
+ frame_rate_);
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_DataRateLimits(),
+ media::video_toolbox::ArrayWithIntegerAndFloat(
+ target_bitrate_ / kBitsPerByte, 1.0f));
+ DLOG_IF(ERROR, !rv) << "Couldn't change session encoding parameters.";
+}
+
+void VTVideoEncodeAccelerator::DestroyTask() {
+ DCHECK(thread_checker_.CalledOnValidThread() ||
+ (encoder_thread_.IsRunning() &&
+ encoder_thread_task_runner_->BelongsToCurrentThread()));
+
+ // Cancel all encoder thread callbacks.
+ encoder_task_weak_factory_.InvalidateWeakPtrs();
+
+ // This call blocks until all pending frames are flushed out.
+ DestroyCompressionSession();
+}
+
+void VTVideoEncodeAccelerator::NotifyError(
+ media::VideoEncodeAccelerator::Error error) {
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+ client_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&Client::NotifyError, client_, error));
+}
+
+// static
+void VTVideoEncodeAccelerator::CompressionCallback(void* encoder_opaque,
+ void* request_opaque,
+ OSStatus status,
+ VTEncodeInfoFlags info,
+ CMSampleBufferRef sbuf) {
+ // This function may be called asynchronously, on a different thread from the
+ // one that calls VTCompressionSessionEncodeFrame.
+ DVLOG(3) << __FUNCTION__;
+
+ auto encoder = reinterpret_cast<VTVideoEncodeAccelerator*>(encoder_opaque);
+ DCHECK(encoder);
+
+ // Release InProgressFrameEncode, since we don't have support to return
+ // timestamps at this point.
+ scoped_ptr<InProgressFrameEncode> request(
+ reinterpret_cast<InProgressFrameEncode*>(request_opaque));
+ request.reset();
+
+ // EncodeOutput holds onto CMSampleBufferRef when posting task between
+ // threads.
+ scoped_ptr<EncodeOutput> encode_output(new EncodeOutput(info, sbuf));
+
+ // This method is NOT called on |encoder_thread_|, so we still need to
+ // post a task back to it to do work.
+ encoder->encoder_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VTVideoEncodeAccelerator::CompressionCallbackTask,
+ encoder->encoder_weak_ptr_, status,
+ base::Passed(&encode_output)));
+}
+
+void VTVideoEncodeAccelerator::CompressionCallbackTask(
+ OSStatus status,
+ scoped_ptr<EncodeOutput> encode_output) {
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+
+ if (status != noErr) {
+ DLOG(ERROR) << " encode failed: " << status;
+ NotifyError(kPlatformFailureError);
+ return;
+ }
+
+ // If there isn't any BitstreamBuffer to copy into, add it to a queue for
+ // later use.
+ if (bitstream_buffer_queue_.empty()) {
+ encoder_output_queue_.push_back(std::move(encode_output));
+ return;
+ }
+
+ scoped_ptr<VTVideoEncodeAccelerator::BitstreamBufferRef> buffer_ref =
+ std::move(bitstream_buffer_queue_.front());
+ bitstream_buffer_queue_.pop_front();
+ ReturnBitstreamBuffer(std::move(encode_output), std::move(buffer_ref));
+}
+
+void VTVideoEncodeAccelerator::ReturnBitstreamBuffer(
+ scoped_ptr<EncodeOutput> encode_output,
+ scoped_ptr<VTVideoEncodeAccelerator::BitstreamBufferRef> buffer_ref) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread());
+
+ if (encode_output->info & VideoToolboxGlue::kVTEncodeInfo_FrameDropped) {
+ DVLOG(2) << " frame dropped";
+ client_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
+ buffer_ref->id, 0, false));
+ return;
+ }
+
+ auto sample_attachments = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(
+ CoreMediaGlue::CMSampleBufferGetSampleAttachmentsArray(
+ encode_output->sample_buffer.get(), true),
+ 0));
+ const bool keyframe =
+ !CFDictionaryContainsKey(sample_attachments,
+ CoreMediaGlue::kCMSampleAttachmentKey_NotSync());
+
+ size_t used_buffer_size = 0;
+ const bool copy_rv = media::video_toolbox::CopySampleBufferToAnnexBBuffer(
+ encode_output->sample_buffer.get(), keyframe, buffer_ref->size,
+ reinterpret_cast<char*>(buffer_ref->shm->memory()), &used_buffer_size);
+ if (!copy_rv) {
+ DLOG(ERROR) << "Cannot copy output from SampleBuffer to AnnexBBuffer.";
+ used_buffer_size = 0;
+ }
+
+ client_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&Client::BitstreamBufferReady, client_,
+ buffer_ref->id, used_buffer_size, keyframe));
+}
+
+bool VTVideoEncodeAccelerator::ResetCompressionSession() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DestroyCompressionSession();
+
+ CFTypeRef attributes_keys[] = {
+ kCVPixelBufferOpenGLCompatibilityKey,
+ kCVPixelBufferIOSurfacePropertiesKey,
+ kCVPixelBufferPixelFormatTypeKey
+ };
+ const int format[] = {
+ CoreVideoGlue::kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange};
+ CFTypeRef attributes_values[] = {
+ kCFBooleanTrue,
+ media::video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0)
+ .release(),
+ media::video_toolbox::ArrayWithIntegers(format, arraysize(format))
+ .release()};
+ const base::ScopedCFTypeRef<CFDictionaryRef> attributes =
+ media::video_toolbox::DictionaryWithKeysAndValues(
+ attributes_keys, attributes_values, arraysize(attributes_keys));
+ for (auto& v : attributes_values)
+ CFRelease(v);
+
+ bool session_rv =
+ CreateCompressionSession(attributes, input_visible_size_, false);
+ if (!session_rv) {
+ DestroyCompressionSession();
+ return false;
+ }
+
+ const bool configure_rv = ConfigureCompressionSession();
+ if (configure_rv)
+ RequestEncodingParametersChange(target_bitrate_, frame_rate_);
+ return configure_rv;
+}
+
+bool VTVideoEncodeAccelerator::CreateCompressionSession(
+ base::ScopedCFTypeRef<CFDictionaryRef> attributes,
+ const gfx::Size& input_size,
+ bool require_hw_encoding) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ std::vector<CFTypeRef> encoder_keys;
+ std::vector<CFTypeRef> encoder_values;
+ if (require_hw_encoding) {
+ encoder_keys.push_back(videotoolbox_glue_
+ ->kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder());
+ encoder_values.push_back(kCFBooleanTrue);
+ } else {
+ encoder_keys.push_back(videotoolbox_glue_
+ ->kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder());
+ encoder_values.push_back(kCFBooleanTrue);
+ }
+ base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec =
+ media::video_toolbox::DictionaryWithKeysAndValues(
+ encoder_keys.data(), encoder_values.data(), encoder_keys.size());
+
+ // Create the compression session.
+ // Note that the encoder object is given to the compression session as the
+ // callback context using a raw pointer. The C API does not allow us to use a
+ // smart pointer, nor is this encoder ref counted. However, this is still
+ // safe, because we 1) we own the compression session and 2) we tear it down
+ // safely. When destructing the encoder, the compression session is flushed
+ // and invalidated. Internally, VideoToolbox will join all of its threads
+ // before returning to the client. Therefore, when control returns to us, we
+ // are guaranteed that the output callback will not execute again.
+ OSStatus status = videotoolbox_glue_->VTCompressionSessionCreate(
+ kCFAllocatorDefault,
+ input_size.width(),
+ input_size.height(),
+ CoreMediaGlue::kCMVideoCodecType_H264,
+ encoder_spec,
+ attributes,
+ nullptr /* compressedDataAllocator */,
+ &VTVideoEncodeAccelerator::CompressionCallback,
+ reinterpret_cast<void*>(this),
+ compression_session_.InitializeInto());
+ if (status != noErr) {
+ DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status;
+ return false;
+ }
+ DVLOG(3) << " VTCompressionSession created with HW encode: "
+ << require_hw_encoding << ", input size=" << input_size.ToString();
+ return true;
+}
+
+bool VTVideoEncodeAccelerator::ConfigureCompressionSession() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(compression_session_);
+
+ media::video_toolbox::SessionPropertySetter session_property_setter(
+ compression_session_, videotoolbox_glue_);
+ bool rv = true;
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_ProfileLevel(),
+ videotoolbox_glue_->kVTProfileLevel_H264_Baseline_AutoLevel());
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_RealTime(), true);
+ rv &= session_property_setter.Set(
+ videotoolbox_glue_->kVTCompressionPropertyKey_AllowFrameReordering(),
+ false);
+ DLOG_IF(ERROR, !rv) << " Setting session property failed.";
+ return rv;
+}
+
+void VTVideoEncodeAccelerator::DestroyCompressionSession() {
+ DCHECK(thread_checker_.CalledOnValidThread() ||
+ (encoder_thread_.IsRunning() &&
+ encoder_thread_task_runner_->BelongsToCurrentThread()));
+
+ if (compression_session_) {
+ videotoolbox_glue_->VTCompressionSessionInvalidate(compression_session_);
+ compression_session_.reset();
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.h b/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.h
new file mode 100644
index 00000000000..aa4b37ed22d
--- /dev/null
+++ b/chromium/content/common/gpu/media/vt_video_encode_accelerator_mac.h
@@ -0,0 +1,142 @@
+// Copyright 2016 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 CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_
+#define CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_
+
+#include "base/mac/scoped_cftyperef.h"
+#include "content/common/content_export.h"
+#include "media/base/mac/videotoolbox_glue.h"
+#include "media/base/mac/videotoolbox_helpers.h"
+#include "media/video/video_encode_accelerator.h"
+
+namespace content {
+
+// VideoToolbox.framework implementation of the VideoEncodeAccelerator
+// interface for MacOSX. VideoToolbox makes no guarantees that it is thread
+// safe, so this object is pinned to the thread on which it is constructed.
+class CONTENT_EXPORT VTVideoEncodeAccelerator
+ : public media::VideoEncodeAccelerator {
+ public:
+ VTVideoEncodeAccelerator();
+ ~VTVideoEncodeAccelerator() override;
+
+ // media::VideoEncodeAccelerator implementation.
+ media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles()
+ override;
+ bool Initialize(media::VideoPixelFormat format,
+ const gfx::Size& input_visible_size,
+ media::VideoCodecProfile output_profile,
+ uint32_t initial_bitrate,
+ Client* client) override;
+ void Encode(const scoped_refptr<media::VideoFrame>& frame,
+ bool force_keyframe) override;
+ void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer) override;
+ void RequestEncodingParametersChange(uint32_t bitrate,
+ uint32_t framerate) override;
+ void Destroy() override;
+
+ private:
+ using CMSampleBufferRef = CoreMediaGlue::CMSampleBufferRef;
+ using VTCompressionSessionRef = VideoToolboxGlue::VTCompressionSessionRef;
+ using VTEncodeInfoFlags = VideoToolboxGlue::VTEncodeInfoFlags;
+
+ // Holds the associated data of a video frame being processed.
+ struct InProgressFrameEncode;
+
+ // Holds output buffers coming from the encoder.
+ struct EncodeOutput;
+
+ // Holds output buffers coming from the client ready to be filled.
+ struct BitstreamBufferRef;
+
+ // Encoding tasks to be run on |encoder_thread_|.
+ void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
+ bool force_keyframe);
+ void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
+ void RequestEncodingParametersChangeTask(uint32_t bitrate,
+ uint32_t framerate);
+ void DestroyTask();
+
+ // Helper function to notify the client of an error on |client_task_runner_|.
+ void NotifyError(media::VideoEncodeAccelerator::Error error);
+
+ // Compression session callback function to handle compressed frames.
+ static void CompressionCallback(void* encoder_opaque,
+ void* request_opaque,
+ OSStatus status,
+ VTEncodeInfoFlags info,
+ CMSampleBufferRef sbuf);
+ void CompressionCallbackTask(OSStatus status,
+ scoped_ptr<EncodeOutput> encode_output);
+
+ // Copy CMSampleBuffer into a BitstreamBuffer and return it to the |client_|.
+ void ReturnBitstreamBuffer(
+ scoped_ptr<EncodeOutput> encode_output,
+ scoped_ptr<VTVideoEncodeAccelerator::BitstreamBufferRef> buffer_ref);
+
+ // Reset the encoder's compression session by destroying the existing one
+ // using DestroyCompressionSession() and creating a new one. The new session
+ // is configured using ConfigureCompressionSession().
+ bool ResetCompressionSession();
+
+ // Create a compression session, with HW encoder enforced if
+ // |require_hw_encoding| is set.
+ bool CreateCompressionSession(
+ base::ScopedCFTypeRef<CFDictionaryRef> attributes,
+ const gfx::Size& input_size,
+ bool require_hw_encoding);
+
+ // Configure the current compression session using current encoder settings.
+ bool ConfigureCompressionSession();
+
+ // Destroy the current compression session if any. Blocks until all pending
+ // frames have been flushed out (similar to EmitFrames without doing any
+ // encoding work).
+ void DestroyCompressionSession();
+
+ // VideoToolboxGlue provides access to VideoToolbox at runtime.
+ const VideoToolboxGlue* videotoolbox_glue_;
+ base::ScopedCFTypeRef<VTCompressionSessionRef> compression_session_;
+
+ gfx::Size input_visible_size_;
+ size_t bitstream_buffer_size_;
+ int32_t frame_rate_;
+ int32_t target_bitrate_;
+
+ // Bitstream buffers ready to be used to return encoded output as a FIFO.
+ std::deque<scoped_ptr<BitstreamBufferRef>> bitstream_buffer_queue_;
+
+ // EncodeOutput needs to be copied into a BitstreamBufferRef as a FIFO.
+ std::deque<scoped_ptr<EncodeOutput>> encoder_output_queue_;
+
+ // Our original calling task runner for the child thread.
+ const scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
+
+ // To expose client callbacks from VideoEncodeAccelerator.
+ // NOTE: all calls to this object *MUST* be executed on
+ // |client_task_runner_|.
+ base::WeakPtr<Client> client_;
+ scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
+
+ // Thread checker to enforce that this object is used on a specific thread.
+ // It is pinned on |client_task_runner_| thread.
+ base::ThreadChecker thread_checker_;
+
+ // This thread services tasks posted from the VEA API entry points by the
+ // GPU child thread and CompressionCallback() posted from device thread.
+ base::Thread encoder_thread_;
+ scoped_refptr<base::SingleThreadTaskRunner> encoder_thread_task_runner_;
+
+ // Declared last to ensure that all weak pointers are invalidated before
+ // other destructors run.
+ base::WeakPtr<VTVideoEncodeAccelerator> encoder_weak_ptr_;
+ base::WeakPtrFactory<VTVideoEncodeAccelerator> encoder_task_weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(VTVideoEncodeAccelerator);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_ENCODE_ACCELERATOR_MAC_H_
diff --git a/chromium/content/common/gpu/stream_texture_android.cc b/chromium/content/common/gpu/stream_texture_android.cc
deleted file mode 100644
index 17d841d8eb1..00000000000
--- a/chromium/content/common/gpu/stream_texture_android.cc
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright (c) 2013 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 "content/common/gpu/stream_texture_android.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/strings/stringize_macros.h"
-#include "content/common/android/surface_texture_peer.h"
-#include "content/common/gpu/gpu_channel.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/context_state.h"
-#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "gpu/command_buffer/service/texture_manager.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_helper.h"
-#include "ui/gl/scoped_binders.h"
-#include "ui/gl/scoped_make_current.h"
-
-namespace content {
-
-using gpu::gles2::ContextGroup;
-using gpu::gles2::GLES2Decoder;
-using gpu::gles2::TextureManager;
-using gpu::gles2::TextureRef;
-
-// static
-bool StreamTexture::Create(GpuCommandBufferStub* owner_stub,
- uint32_t client_texture_id,
- int stream_id) {
- GLES2Decoder* decoder = owner_stub->decoder();
- TextureManager* texture_manager =
- decoder->GetContextGroup()->texture_manager();
- TextureRef* texture = texture_manager->GetTexture(client_texture_id);
-
- if (texture && (!texture->texture()->target() ||
- texture->texture()->target() == GL_TEXTURE_EXTERNAL_OES)) {
-
- // TODO: Ideally a valid image id was returned to the client so that
- // it could then call glBindTexImage2D() for doing the following.
- scoped_refptr<gl::GLImage> gl_image(
- new StreamTexture(owner_stub, stream_id, texture->service_id()));
- gfx::Size size = gl_image->GetSize();
- texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
- texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA,
- size.width(), size.height(), 1, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, gfx::Rect(size));
- texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0,
- gl_image.get(),
- gpu::gles2::Texture::UNBOUND);
- return true;
- }
-
- return false;
-}
-
-StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
- int32_t route_id,
- uint32_t texture_id)
- : surface_texture_(gfx::SurfaceTexture::Create(texture_id)),
- size_(0, 0),
- has_valid_frame_(false),
- has_pending_frame_(false),
- owner_stub_(owner_stub),
- route_id_(route_id),
- has_listener_(false),
- texture_id_(texture_id),
- framebuffer_(0),
- vertex_shader_(0),
- fragment_shader_(0),
- program_(0),
- vertex_buffer_(0),
- u_xform_location_(-1),
- weak_factory_(this) {
- owner_stub->AddDestructionObserver(this);
- memset(current_matrix_, 0, sizeof(current_matrix_));
- owner_stub->channel()->AddRoute(route_id, this);
- surface_texture_->SetFrameAvailableCallback(base::Bind(
- &StreamTexture::OnFrameAvailable, weak_factory_.GetWeakPtr()));
-}
-
-StreamTexture::~StreamTexture() {
- if (owner_stub_) {
- owner_stub_->RemoveDestructionObserver(this);
- owner_stub_->channel()->RemoveRoute(route_id_);
- }
-}
-
-void StreamTexture::OnWillDestroyStub() {
- owner_stub_->RemoveDestructionObserver(this);
- owner_stub_->channel()->RemoveRoute(route_id_);
-
- if (framebuffer_) {
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current(MakeStubCurrent());
-
- glDeleteProgram(program_);
- glDeleteShader(vertex_shader_);
- glDeleteShader(fragment_shader_);
- glDeleteBuffersARB(1, &vertex_buffer_);
- glDeleteFramebuffersEXT(1, &framebuffer_);
- program_ = 0;
- vertex_shader_ = 0;
- fragment_shader_ = 0;
- vertex_buffer_ = 0;
- framebuffer_ = 0;
- u_xform_location_ = -1;
- }
-
- owner_stub_ = NULL;
-
- // If the owner goes away, there is no need to keep the SurfaceTexture around.
- // The GL texture will keep working regardless with the currently bound frame.
- surface_texture_ = NULL;
-}
-
-void StreamTexture::Destroy(bool have_context) {
- NOTREACHED();
-}
-
-scoped_ptr<ui::ScopedMakeCurrent> StreamTexture::MakeStubCurrent() {
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
- bool needs_make_current =
- !owner_stub_->decoder()->GetGLContext()->IsCurrent(NULL);
- // On Android we should not have to perform a real context switch here when
- // using virtual contexts.
- DCHECK(!needs_make_current ||
- !owner_stub_->decoder()
- ->GetContextGroup()
- ->feature_info()
- ->workarounds()
- .use_virtualized_gl_contexts);
- if (needs_make_current) {
- scoped_make_current.reset(new ui::ScopedMakeCurrent(
- owner_stub_->decoder()->GetGLContext(), owner_stub_->surface()));
- }
- return scoped_make_current;
-}
-
-void StreamTexture::UpdateTexImage() {
- DCHECK(surface_texture_.get());
- DCHECK(owner_stub_);
-
- if (!has_pending_frame_) return;
-
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current(MakeStubCurrent());
-
- surface_texture_->UpdateTexImage();
-
- has_valid_frame_ = true;
- has_pending_frame_ = false;
-
- float mtx[16];
- surface_texture_->GetTransformMatrix(mtx);
-
- if (memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
- memcpy(current_matrix_, mtx, sizeof(mtx));
-
- if (has_listener_) {
- GpuStreamTextureMsg_MatrixChanged_Params params;
- memcpy(&params.m00, mtx, sizeof(mtx));
- owner_stub_->channel()->Send(
- new GpuStreamTextureMsg_MatrixChanged(route_id_, params));
- }
- }
-
- if (scoped_make_current.get()) {
- // UpdateTexImage() implies glBindTexture().
- // The cmd decoder takes care of restoring the binding for this GLImage as
- // far as the current context is concerned, but if we temporarily change
- // it, we have to keep the state intact in *that* context also.
- const gpu::gles2::ContextState* state =
- owner_stub_->decoder()->GetContextState();
- const gpu::gles2::TextureUnit& active_unit =
- state->texture_units[state->active_texture_unit];
- glBindTexture(GL_TEXTURE_EXTERNAL_OES,
- active_unit.bound_texture_external_oes.get()
- ? active_unit.bound_texture_external_oes->service_id()
- : 0);
- }
-}
-
-bool StreamTexture::CopyTexImage(unsigned target) {
- if (target == GL_TEXTURE_2D) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- return CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(), gfx::Rect(size_));
- }
-
- if (target != GL_TEXTURE_EXTERNAL_OES)
- return false;
-
- if (!owner_stub_ || !surface_texture_.get())
- return true;
-
- GLint texture_id;
- glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
- DCHECK(texture_id);
-
- // The following code only works if we're being asked to copy into
- // |texture_id_|. Copying into a different texture is not supported.
- if (static_cast<unsigned>(texture_id) != texture_id_)
- return false;
-
- UpdateTexImage();
-
- TextureManager* texture_manager =
- owner_stub_->decoder()->GetContextGroup()->texture_manager();
- gpu::gles2::Texture* texture =
- texture_manager->GetTextureForServiceId(texture_id_);
- if (texture) {
- // By setting image state to UNBOUND instead of COPIED we ensure that
- // CopyTexImage() is called each time the surface texture is used for
- // drawing.
- texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gpu::gles2::Texture::UNBOUND);
- }
-
- return true;
-}
-
-void StreamTexture::OnFrameAvailable() {
- has_pending_frame_ = true;
- if (has_listener_ && owner_stub_) {
- owner_stub_->channel()->Send(
- new GpuStreamTextureMsg_FrameAvailable(route_id_));
- }
-}
-
-gfx::Size StreamTexture::GetSize() {
- return size_;
-}
-
-unsigned StreamTexture::GetInternalFormat() {
- return GL_RGBA;
-}
-
-bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(StreamTexture, message)
- IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_StartListening, OnStartListening)
- IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_EstablishPeer, OnEstablishPeer)
- IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_SetSize, OnSetSize)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- DCHECK(handled);
- return handled;
-}
-
-void StreamTexture::OnStartListening() {
- DCHECK(!has_listener_);
- has_listener_ = true;
-}
-
-void StreamTexture::OnEstablishPeer(int32_t primary_id, int32_t secondary_id) {
- if (!owner_stub_)
- return;
-
- base::ProcessHandle process = owner_stub_->channel()->GetClientPID();
-
- SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
- process, surface_texture_, primary_id, secondary_id);
-}
-
-bool StreamTexture::BindTexImage(unsigned target) {
- NOTREACHED();
- return false;
-}
-
-void StreamTexture::ReleaseTexImage(unsigned target) {
- NOTREACHED();
-}
-
-bool StreamTexture::CopyTexSubImage(unsigned target,
- const gfx::Point& offset,
- const gfx::Rect& rect) {
- if (target != GL_TEXTURE_2D)
- return false;
-
- if (!owner_stub_ || !surface_texture_.get())
- return true;
-
- if (!offset.IsOrigin()) {
- LOG(ERROR) << "Non-origin offset is not supported";
- return false;
- }
-
- if (rect != gfx::Rect(size_)) {
- LOG(ERROR) << "Sub-rectangle is not supported";
- return false;
- }
-
- GLint target_texture = 0;
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &target_texture);
- DCHECK(target_texture);
-
- UpdateTexImage();
-
- if (!framebuffer_) {
- glGenFramebuffersEXT(1, &framebuffer_);
-
- // This vertex shader introduces a y flip before applying the stream
- // texture matrix. This is required because the stream texture matrix
- // Android provides is intended to be used in a y-up coordinate system,
- // whereas Chromium expects y-down.
-
- // clang-format off
- const char kVertexShader[] = STRINGIZE(
- attribute vec2 a_position;
- varying vec2 v_texCoord;
- uniform mat4 u_xform;
- void main() {
- gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
- vec2 uv_untransformed = a_position * vec2(0.5, -0.5) + vec2(0.5, 0.5);
- v_texCoord = (u_xform * vec4(uv_untransformed, 0.0, 1.0)).xy;
- }
- );
- const char kFragmentShader[] =
- "#extension GL_OES_EGL_image_external : require\n" STRINGIZE(
- precision mediump float;
- uniform samplerExternalOES a_texture;
- varying vec2 v_texCoord;
- void main() {
- gl_FragColor = texture2D(a_texture, v_texCoord);
- }
- );
- // clang-format on
-
- vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer();
- vertex_shader_ = gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader);
- fragment_shader_ =
- gfx::GLHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShader);
- program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_);
- gfx::ScopedUseProgram use_program(program_);
- int sampler_location = glGetUniformLocation(program_, "a_texture");
- DCHECK_NE(-1, sampler_location);
- glUniform1i(sampler_location, 0);
- u_xform_location_ = glGetUniformLocation(program_, "u_xform");
- DCHECK_NE(-1, u_xform_location_);
- }
-
- gfx::ScopedActiveTexture active_texture(GL_TEXTURE0);
- // UpdateTexImage() call below will bind the surface texture to
- // TEXTURE_EXTERNAL_OES. This scoped texture binder will restore the current
- // binding before this function returns.
- gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, texture_id_);
-
- {
- gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_);
- gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height());
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, target_texture, 0);
- DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
- glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
- gfx::ScopedUseProgram use_program(program_);
-
- glUniformMatrix4fv(u_xform_location_, 1, false, current_matrix_);
- gfx::GLHelper::DrawQuad(vertex_buffer_);
-
- // Detach the output texture from the fbo.
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, 0, 0);
- }
- return true;
-}
-
-bool StreamTexture::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
- int z_order,
- gfx::OverlayTransform transform,
- const gfx::Rect& bounds_rect,
- const gfx::RectF& crop_rect) {
- NOTREACHED();
- return false;
-}
-
-void StreamTexture::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
- uint64_t process_tracing_id,
- const std::string& dump_name) {
- // TODO(ericrk): Add OnMemoryDump for GLImages. crbug.com/514914
-}
-
-} // namespace content
diff --git a/chromium/content/common/gpu/stream_texture_android.h b/chromium/content/common/gpu/stream_texture_android.h
deleted file mode 100644
index e19fc1b321a..00000000000
--- a/chromium/content/common/gpu/stream_texture_android.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2013 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 CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_
-#define CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/gpu/gpu_command_buffer_stub.h"
-#include "ipc/ipc_listener.h"
-#include "ui/gl/android/surface_texture.h"
-#include "ui/gl/gl_image.h"
-
-namespace ui {
-class ScopedMakeCurrent;
-}
-
-namespace gfx {
-class Size;
-}
-
-namespace content {
-
-class StreamTexture : public gl::GLImage,
- public IPC::Listener,
- public GpuCommandBufferStub::DestructionObserver {
- public:
- static bool Create(GpuCommandBufferStub* owner_stub,
- uint32_t client_texture_id,
- int stream_id);
-
- private:
- StreamTexture(GpuCommandBufferStub* owner_stub,
- int32_t route_id,
- uint32_t texture_id);
- ~StreamTexture() override;
-
- // gl::GLImage implementation:
- void Destroy(bool have_context) override;
- gfx::Size GetSize() override;
- unsigned GetInternalFormat() override;
- bool BindTexImage(unsigned target) override;
- void ReleaseTexImage(unsigned target) override;
- bool CopyTexImage(unsigned target) override;
- bool CopyTexSubImage(unsigned target,
- const gfx::Point& offset,
- const gfx::Rect& rect) override;
- bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
- int z_order,
- gfx::OverlayTransform transform,
- const gfx::Rect& bounds_rect,
- const gfx::RectF& crop_rect) override;
- void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
- uint64_t process_tracing_id,
- const std::string& dump_name) override;
-
- // GpuCommandBufferStub::DestructionObserver implementation.
- void OnWillDestroyStub() override;
-
- scoped_ptr<ui::ScopedMakeCurrent> MakeStubCurrent();
-
- void UpdateTexImage();
-
- // Called when a new frame is available for the SurfaceTexture.
- void OnFrameAvailable();
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& message) override;
-
- // IPC message handlers:
- void OnStartListening();
- void OnEstablishPeer(int32_t primary_id, int32_t secondary_id);
- void OnSetSize(const gfx::Size& size) { size_ = size; }
-
- scoped_refptr<gfx::SurfaceTexture> surface_texture_;
-
- // Current transform matrix of the surface texture.
- float current_matrix_[16];
-
- // Current size of the surface texture.
- gfx::Size size_;
-
- // Whether we ever bound a valid frame.
- bool has_valid_frame_;
-
- // Whether a new frame is available that we should update to.
- bool has_pending_frame_;
-
- GpuCommandBufferStub* owner_stub_;
- int32_t route_id_;
- bool has_listener_;
- uint32_t texture_id_;
-
- unsigned framebuffer_;
- unsigned vertex_shader_;
- unsigned fragment_shader_;
- unsigned program_;
- unsigned vertex_buffer_;
- int u_xform_location_;
-
- base::WeakPtrFactory<StreamTexture> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(StreamTexture);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_
diff --git a/chromium/content/common/gpu/x_util.h b/chromium/content/common/gpu/x_util.h
deleted file mode 100644
index 99687566356..00000000000
--- a/chromium/content/common/gpu/x_util.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_GPU_X_UTIL_H_
-#define CONTENT_COMMON_GPU_X_UTIL_H_
-
-// Some X-Windows specific stuff. This can be included on any platform, and will
-// be a NOP on non-Linux ones.
-
-#include "build/build_config.h"
-#include "content/common/gpu/gpu_config.h"
-
-#if defined(USE_X11)
-
-namespace content {
-
-// Forward declares ------------------------------------------------------------
-//
-// X Windows headers do a lot of evil stuff, like "#define Status int" which
-// will cause many problems when combined with our other header files (like
-// ones that define a class local enum called "Status."
-//
-// These definitions are not Kosher, but allow us to remove this dependency and
-// actually compile X at all.
-
-typedef unsigned long XID;
-
-extern "C" {
-
-typedef struct _XDisplay Display;
-typedef struct __GLXcontextRec *GLXContext;
-
-} // extern "C"
-
-} // namespace content
-
-#endif // USE_X11
-
-#endif // CONTENT_COMMON_GPU_X_UTIL_H_
diff --git a/chromium/content/common/gpu_host_messages.h b/chromium/content/common/gpu_host_messages.h
new file mode 100644
index 00000000000..0705be08955
--- /dev/null
+++ b/chromium/content/common/gpu_host_messages.h
@@ -0,0 +1,300 @@
+// Copyright 2016 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.
+
+// Multiply-included message file, hence no include guard here, but see below
+// for a much smaller-than-usual include guard section.
+
+#include "build/build_config.h"
+#include "content/common/content_export.h"
+#include "content/common/establish_channel_params.h"
+#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/command_buffer/common/value_state.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/config/gpu_info.h"
+#include "gpu/ipc/common/gpu_command_buffer_traits.h"
+#include "gpu/ipc/common/gpu_memory_uma_stats.h"
+#include "gpu/ipc/common/gpu_param_traits.h"
+#include "gpu/ipc/common/memory_stats.h"
+#include "gpu/ipc/common/surface_handle.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
+#include "ui/events/ipc/latency_info_param_traits.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
+#include "url/gurl.h"
+#include "url/ipc/url_param_traits.h"
+
+#if defined(OS_MACOSX)
+#include "content/common/accelerated_surface_buffers_swapped_params_mac.h"
+#include "content/common/buffer_presented_params_mac.h"
+#include "ui/base/cocoa/remote_layer_api.h"
+#include "ui/gfx/mac/io_surface.h"
+#endif
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+
+#define IPC_MESSAGE_START GpuMsgStart
+
+IPC_STRUCT_TRAITS_BEGIN(gpu::GPUMemoryUmaStats)
+ IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_current)
+ IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_max)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(gpu::VideoMemoryUsageStats)
+ IPC_STRUCT_TRAITS_MEMBER(process_map)
+ IPC_STRUCT_TRAITS_MEMBER(bytes_allocated)
+ IPC_STRUCT_TRAITS_MEMBER(bytes_allocated_historical_max)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(gpu::VideoMemoryUsageStats::ProcessStats)
+ IPC_STRUCT_TRAITS_MEMBER(video_memory)
+ IPC_STRUCT_TRAITS_MEMBER(has_duplicates)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBuffer_Params)
+ IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferId, id)
+ IPC_STRUCT_MEMBER(gfx::Size, size)
+ IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
+ IPC_STRUCT_MEMBER(gfx::BufferUsage, usage)
+ IPC_STRUCT_MEMBER(int32_t, client_id)
+ IPC_STRUCT_MEMBER(gpu::SurfaceHandle, surface_handle)
+IPC_STRUCT_END()
+
+IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBufferFromHandle_Params)
+ IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferHandle, handle)
+ IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferId, id)
+ IPC_STRUCT_MEMBER(gfx::Size, size)
+ IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
+ IPC_STRUCT_MEMBER(int32_t, client_id)
+IPC_STRUCT_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::EstablishChannelParams)
+ IPC_STRUCT_TRAITS_MEMBER(client_id)
+ IPC_STRUCT_TRAITS_MEMBER(client_tracing_id)
+ IPC_STRUCT_TRAITS_MEMBER(preempts)
+ IPC_STRUCT_TRAITS_MEMBER(allow_view_command_buffers)
+ IPC_STRUCT_TRAITS_MEMBER(allow_real_time_streams)
+IPC_STRUCT_TRAITS_END()
+
+#if defined(OS_MACOSX)
+IPC_STRUCT_TRAITS_BEGIN(content::AcceleratedSurfaceBuffersSwappedParams)
+ IPC_STRUCT_TRAITS_MEMBER(surface_id)
+ // Only one of ca_context_id or io_surface may be non-0.
+ IPC_STRUCT_TRAITS_MEMBER(ca_context_id)
+ IPC_STRUCT_TRAITS_MEMBER(io_surface)
+ IPC_STRUCT_TRAITS_MEMBER(size)
+ IPC_STRUCT_TRAITS_MEMBER(scale_factor)
+ IPC_STRUCT_TRAITS_MEMBER(latency_info)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::BufferPresentedParams)
+ // The vsync parameters, to synchronize presentation with the display.
+ IPC_STRUCT_TRAITS_MEMBER(surface_id)
+ IPC_STRUCT_TRAITS_MEMBER(vsync_timebase)
+ IPC_STRUCT_TRAITS_MEMBER(vsync_interval)
+IPC_STRUCT_TRAITS_END()
+#endif
+
+IPC_STRUCT_TRAITS_BEGIN(gpu::GpuPreferences)
+ IPC_STRUCT_TRAITS_MEMBER(single_process)
+ IPC_STRUCT_TRAITS_MEMBER(in_process_gpu)
+ IPC_STRUCT_TRAITS_MEMBER(ui_prioritize_in_gpu_process)
+ IPC_STRUCT_TRAITS_MEMBER(disable_accelerated_video_decode)
+#if defined(OS_CHROMEOS)
+ IPC_STRUCT_TRAITS_MEMBER(disable_vaapi_accelerated_video_encode)
+#endif
+#if defined(ENABLE_WEBRTC)
+ IPC_STRUCT_TRAITS_MEMBER(disable_web_rtc_hw_encoding)
+#endif
+#if defined(OS_WIN)
+ IPC_STRUCT_TRAITS_MEMBER(enable_accelerated_vpx_decode)
+#endif
+ IPC_STRUCT_TRAITS_MEMBER(compile_shader_always_succeeds)
+ IPC_STRUCT_TRAITS_MEMBER(disable_gl_error_limit)
+ IPC_STRUCT_TRAITS_MEMBER(disable_glsl_translator)
+ IPC_STRUCT_TRAITS_MEMBER(disable_gpu_driver_bug_workarounds)
+ IPC_STRUCT_TRAITS_MEMBER(disable_shader_name_hashing)
+ IPC_STRUCT_TRAITS_MEMBER(enable_gpu_command_logging)
+ IPC_STRUCT_TRAITS_MEMBER(enable_gpu_debugging)
+ IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging_gpu)
+ IPC_STRUCT_TRAITS_MEMBER(disable_gpu_program_cache)
+ IPC_STRUCT_TRAITS_MEMBER(enforce_gl_minimums)
+ IPC_STRUCT_TRAITS_MEMBER(force_gpu_mem_available)
+ IPC_STRUCT_TRAITS_MEMBER(gpu_program_cache_size)
+ IPC_STRUCT_TRAITS_MEMBER(disable_gpu_shader_disk_cache)
+ IPC_STRUCT_TRAITS_MEMBER(enable_share_group_async_texture_upload)
+ IPC_STRUCT_TRAITS_MEMBER(enable_subscribe_uniform_extension)
+ IPC_STRUCT_TRAITS_MEMBER(enable_threaded_texture_mailboxes)
+ IPC_STRUCT_TRAITS_MEMBER(gl_shader_interm_output)
+ IPC_STRUCT_TRAITS_MEMBER(emulate_shader_precision)
+ IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging)
+ IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_tracing)
+ IPC_STRUCT_TRAITS_MEMBER(enable_unsafe_es3_apis)
+IPC_STRUCT_TRAITS_END()
+
+//------------------------------------------------------------------------------
+// GPU Messages
+// These are messages from the browser to the GPU process.
+
+// Tells the GPU process to initialize itself. The browser explicitly
+// requests this be done so that we are guaranteed that the channel is set
+// up between the browser and GPU process before doing any work that might
+// potentially crash the GPU process. Detection of the child process
+// exiting abruptly is predicated on having the IPC channel set up.
+IPC_MESSAGE_CONTROL1(GpuMsg_Initialize,
+ gpu::GpuPreferences /* gpu_prefernces */)
+
+// Tells the GPU process to shutdown itself.
+IPC_MESSAGE_CONTROL0(GpuMsg_Finalize)
+
+// Tells the GPU process to create a new channel for communication with a
+// given client. The channel name is returned in a
+// GpuHostMsg_ChannelEstablished message. The client ID is passed so
+// that the GPU process reuses an existing channel to that process if it exists.
+// This ID is a unique opaque identifier generated by the browser process.
+// The client_tracing_id is a unique ID used for the purposes of tracing.
+IPC_MESSAGE_CONTROL1(GpuMsg_EstablishChannel,
+ content::EstablishChannelParams /* params */)
+
+// Tells the GPU process to close the channel identified by |client_id|.
+// If no channel can be identified, do nothing.
+IPC_MESSAGE_CONTROL1(GpuMsg_CloseChannel, int32_t /* client_id */)
+
+// Tells the GPU process to create a new gpu memory buffer.
+IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBuffer,
+ GpuMsg_CreateGpuMemoryBuffer_Params)
+
+// Tells the GPU process to create a new gpu memory buffer from an existing
+// handle.
+IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBufferFromHandle,
+ GpuMsg_CreateGpuMemoryBufferFromHandle_Params)
+
+// Tells the GPU process to destroy buffer.
+IPC_MESSAGE_CONTROL3(GpuMsg_DestroyGpuMemoryBuffer,
+ gfx::GpuMemoryBufferId, /* id */
+ int32_t, /* client_id */
+ gpu::SyncToken /* sync_token */)
+
+// Tells the GPU process to create a context for collecting graphics card
+// information.
+IPC_MESSAGE_CONTROL0(GpuMsg_CollectGraphicsInfo)
+
+// Tells the GPU process to report video_memory information for the task manager
+IPC_MESSAGE_CONTROL0(GpuMsg_GetVideoMemoryUsageStats)
+
+#if defined(OS_MACOSX)
+// Tells the GPU process that the browser process has handled the swap
+// buffers or post sub-buffer request.
+IPC_MESSAGE_CONTROL1(AcceleratedSurfaceMsg_BufferPresented,
+ content::BufferPresentedParams)
+#endif
+
+#if defined(OS_ANDROID)
+// Tells the GPU process to wake up the GPU because we're about to draw.
+IPC_MESSAGE_CONTROL0(GpuMsg_WakeUpGpu)
+#endif
+
+// Tells the GPU process to remove all contexts.
+IPC_MESSAGE_CONTROL0(GpuMsg_Clean)
+
+// Tells the GPU process to crash.
+IPC_MESSAGE_CONTROL0(GpuMsg_Crash)
+
+// Tells the GPU process to hang.
+IPC_MESSAGE_CONTROL0(GpuMsg_Hang)
+
+// Tells the GPU process to disable the watchdog thread.
+IPC_MESSAGE_CONTROL0(GpuMsg_DisableWatchdog)
+
+// Tells the GPU process that the browser has seen a GPU switch.
+IPC_MESSAGE_CONTROL0(GpuMsg_GpuSwitched)
+
+// Sends an input event to the gpu service.
+IPC_MESSAGE_CONTROL3(GpuMsg_UpdateValueState,
+ int, /* client_id */
+ unsigned int, /* target */
+ gpu::ValueState /* valuestate */)
+
+//------------------------------------------------------------------------------
+// GPU Host Messages
+// These are messages to the browser.
+
+// Response from GPU to a GputMsg_Initialize message.
+IPC_MESSAGE_CONTROL2(GpuHostMsg_Initialized,
+ bool /* result */,
+ ::gpu::GPUInfo /* gpu_info */)
+
+// Response from GPU to a GpuHostMsg_EstablishChannel message.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_ChannelEstablished,
+ IPC::ChannelHandle /* channel_handle */)
+
+// Message from GPU to notify to destroy the channel.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_DestroyChannel, int32_t /* client_id */)
+
+// Message to cache the given shader information.
+IPC_MESSAGE_CONTROL3(GpuHostMsg_CacheShader,
+ int32_t /* client_id */,
+ std::string /* key */,
+ std::string /* shader */)
+
+// Message to the GPU that a shader was loaded from disk.
+IPC_MESSAGE_CONTROL1(GpuMsg_LoadedShader, std::string /* encoded shader */)
+
+// Response from GPU to a GpuMsg_CreateGpuMemoryBuffer message.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_GpuMemoryBufferCreated,
+ gfx::GpuMemoryBufferHandle /* handle */)
+
+// Response from GPU to a GpuMsg_CollectGraphicsInfo.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_GraphicsInfoCollected,
+ gpu::GPUInfo /* GPU logging stats */)
+
+// Response from GPU to a GpuMsg_GetVideoMemory.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_VideoMemoryUsageStats,
+ gpu::VideoMemoryUsageStats /* GPU memory stats */)
+
+#if defined(OS_MACOSX)
+// Tells the browser that an accelerated surface has swapped.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
+ content::AcceleratedSurfaceBuffersSwappedParams)
+#endif
+
+#if defined(OS_WIN)
+IPC_MESSAGE_CONTROL2(GpuHostMsg_AcceleratedSurfaceCreatedChildWindow,
+ gpu::SurfaceHandle /* parent_window */,
+ gpu::SurfaceHandle /* child_window */)
+#endif
+
+IPC_MESSAGE_CONTROL1(GpuHostMsg_DidCreateOffscreenContext, GURL /* url */)
+
+IPC_MESSAGE_CONTROL3(GpuHostMsg_DidLoseContext,
+ bool /* offscreen */,
+ gpu::error::ContextLostReason /* reason */,
+ GURL /* url */)
+
+IPC_MESSAGE_CONTROL1(GpuHostMsg_DidDestroyOffscreenContext, GURL /* url */)
+
+// Tells the browser about GPU memory usage statistics for UMA logging.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_GpuMemoryUmaStats,
+ gpu::GPUMemoryUmaStats /* GPU memory UMA stats */)
+
+// Tells the browser that a context has subscribed to a new target and
+// the browser should start sending the corresponding information
+IPC_MESSAGE_CONTROL2(GpuHostMsg_AddSubscription,
+ int32_t /* client_id */,
+ unsigned int /* target */)
+
+// Tells the browser that no contexts are subscribed to the target anymore
+// so the browser should stop sending the corresponding information
+IPC_MESSAGE_CONTROL2(GpuHostMsg_RemoveSubscription,
+ int32_t /* client_id */,
+ unsigned int /* target */)
+
+// Message from GPU to add a GPU log message to the about:gpu page.
+IPC_MESSAGE_CONTROL3(GpuHostMsg_OnLogMessage,
+ int /*severity*/,
+ std::string /* header */,
+ std::string /* message */)
diff --git a/chromium/content/common/gpu/gpu_process_launch_causes.h b/chromium/content/common/gpu_process_launch_causes.h
index 1c280761ef9..b7acd351152 100644
--- a/chromium/content/common/gpu/gpu_process_launch_causes.h
+++ b/chromium/content/common/gpu_process_launch_causes.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_COMMON_GPU_GPU_PROCESS_LAUNCH_CAUSES_H_
-#define CONTENT_COMMON_GPU_GPU_PROCESS_LAUNCH_CAUSES_H_
+#ifndef CONTENT_COMMON_GPU_PROCESS_LAUNCH_CAUSES_H_
+#define CONTENT_COMMON_GPU_PROCESS_LAUNCH_CAUSES_H_
namespace content {
@@ -23,7 +23,7 @@ enum CauseForGpuLaunch {
CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE,
CAUSE_FOR_GPU_LAUNCH_JPEGDECODEACCELERATOR_INITIALIZE,
CAUSE_FOR_GPU_LAUNCH_MOJO_SETUP,
- CAUSE_FOR_GPU_LAUNCH_ARCVIDEOACCELERATOR,
+ CAUSE_FOR_GPU_LAUNCH_GET_GPU_SERVICE_REGISTRY,
// All new values should be inserted above this point so that
// existing values continue to match up with those in histograms.xml.
@@ -32,4 +32,4 @@ enum CauseForGpuLaunch {
} // namespace content
-#endif // CONTENT_COMMON_GPU_GPU_PROCESS_LAUNCH_CAUSES_H_
+#endif // CONTENT_COMMON_GPU_PROCESS_LAUNCH_CAUSES_H_
diff --git a/chromium/content/common/host_discardable_shared_memory_manager.cc b/chromium/content/common/host_discardable_shared_memory_manager.cc
index 7a6d480d295..d8d141cdaa8 100644
--- a/chromium/content/common/host_discardable_shared_memory_manager.cc
+++ b/chromium/content/common/host_discardable_shared_memory_manager.cc
@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "base/memory/discardable_memory.h"
#include "base/numerics/safe_math.h"
+#include "base/process/memory.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
@@ -190,6 +191,9 @@ HostDiscardableSharedMemoryManager::current() {
scoped_ptr<base::DiscardableMemory>
HostDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
size_t size) {
+ // TODO(reveman): Temporary diagnostics for http://crbug.com/577786.
+ CHECK_NE(size, 0u);
+
DiscardableSharedMemoryId new_id =
g_next_discardable_shared_memory_id.GetNext();
base::ProcessHandle current_process_handle = base::GetCurrentProcessHandle();
@@ -200,10 +204,10 @@ HostDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
AllocateLockedDiscardableSharedMemory(current_process_handle,
ChildProcessHost::kInvalidUniqueID,
size, new_id, &handle);
- CHECK(base::SharedMemory::IsHandleValid(handle));
scoped_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory(handle));
- CHECK(memory->Map(size));
+ if (!memory->Map(size))
+ base::TerminateBecauseOutOfMemory(size);
// Close file descriptor to avoid running out.
memory->Close();
return make_scoped_ptr(new DiscardableMemoryImpl(
diff --git a/chromium/content/common/host_discardable_shared_memory_manager.h b/chromium/content/common/host_discardable_shared_memory_manager.h
index 3965f1d4c5f..834afe75b3d 100644
--- a/chromium/content/common/host_discardable_shared_memory_manager.h
+++ b/chromium/content/common/host_discardable_shared_memory_manager.h
@@ -18,6 +18,7 @@
#include "base/memory/discardable_shared_memory.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
diff --git a/chromium/content/common/host_shared_bitmap_manager.cc b/chromium/content/common/host_shared_bitmap_manager.cc
index d41ec392be5..e666f9b18c4 100644
--- a/chromium/content/common/host_shared_bitmap_manager.cc
+++ b/chromium/content/common/host_shared_bitmap_manager.cc
@@ -202,13 +202,8 @@ bool HostSharedBitmapManager::ChildAllocatedSharedBitmap(
new BitmapData(process_handle, buffer_size));
handle_map_[id] = data;
-#if defined(OS_WIN)
- data->memory = make_scoped_ptr(
- new base::SharedMemory(handle, false, data->process_handle));
-#else
data->memory =
make_scoped_ptr(new base::SharedMemory(handle, false));
-#endif
data->memory->Map(data->buffer_size);
data->memory->Close();
return true;
diff --git a/chromium/content/common/id_type.h b/chromium/content/common/id_type.h
deleted file mode 100644
index cc25fa5ac29..00000000000
--- a/chromium/content/common/id_type.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2016 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 CONTENT_COMMON_ID_TYPE_H_
-#define CONTENT_COMMON_ID_TYPE_H_
-
-#include <stdint.h>
-#include <ostream>
-#include <type_traits>
-
-#include "base/containers/hash_tables.h"
-
-// IdType32<>, IdType64<>, etc. wrap an integer id in a custom, type-safe type.
-//
-// IdType32<Foo> is an alternative to int, for a class Foo with methods like:
-//
-// int GetId() { return id_; };
-// static Foo* FromId(int id) { return g_all_foos_by_id[id]; }
-//
-// Such methods are a standard means of safely referring to objects across
-// thread and process boundaries. But if a nearby class Bar also represents
-// its IDs as a bare int, horrific mixups are possible -- one example, of many,
-// is http://crrev.com/365437. IdType<> offers compile-time protection against
-// such mishaps, since IdType32<Foo> is incompatible with IdType32<Bar>, even
-// though both just compile down to an int32_t.
-//
-// Templates in this file:
-// IdType32<T> / IdTypeU32<T>: Signed / unsigned 32-bit IDs
-// IdType64<T> / IdTypeU64<T>: Signed / unsigned 64-bit IDs
-// IdType<>: For when you need a different underlying type or
-// a default/invalid value other than zero.
-//
-// IdType32<Foo> behaves just like an int32_t in the following aspects:
-// - it can be used as a key in std::map and/or base::hash_map;
-// - it can be used as an argument to DCHECK_EQ or streamed to LOG(ERROR);
-// - it has the same memory footprint and runtime overhead as int32_t;
-// - it can be copied by memcpy.
-//
-// IdType32<Foo> has the following differences from a bare int32_t:
-// - it forces coercions to go through GetUnsafeValue and FromUnsafeValue;
-// - it restricts the set of available operations (i.e. no multiplication);
-// - it ensures initialization to zero and allows checking against
-// default-initialized values via is_null method.
-
-namespace content {
-
-template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
-class IdType {
- public:
- IdType() : value_(kInvalidValue) {}
- bool is_null() const { return value_ == kInvalidValue; }
-
- static IdType FromUnsafeValue(WrappedType value) { return IdType(value); }
- WrappedType GetUnsafeValue() const { return value_; }
-
- IdType(const IdType& other) = default;
- IdType& operator=(const IdType& other) = default;
-
- bool operator==(const IdType& other) const { return value_ == other.value_; }
- bool operator!=(const IdType& other) const { return value_ != other.value_; }
- bool operator<(const IdType& other) const { return value_ < other.value_; }
-
- protected:
- explicit IdType(WrappedType val) : value_(val) {}
-
- private:
- // In theory WrappedType could be any type that supports ==, <, <<, std::hash,
- // etc., but to make things simpler (both for users and for maintainers) we
- // explicitly restrict the design space to integers. This means the users
- // can safely assume that IdType is relatively small and cheap to copy
- // and the maintainers don't have to worry about WrappedType being a complex
- // type (i.e. std::string or std::pair or a move-only type).
- using IntegralWrappedType =
- typename std::enable_if<std::is_integral<WrappedType>::value,
- WrappedType>::type;
- IntegralWrappedType value_;
-};
-
-// Type aliases for convenience:
-template <typename TypeMarker>
-using IdType32 = IdType<TypeMarker, int32_t, 0>;
-template <typename TypeMarker>
-using IdTypeU32 = IdType<TypeMarker, uint32_t, 0>;
-template <typename TypeMarker>
-using IdType64 = IdType<TypeMarker, int64_t, 0>;
-template <typename TypeMarker>
-using IdTypeU64 = IdType<TypeMarker, uint64_t, 0>;
-
-template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
-std::ostream& operator<<(
- std::ostream& stream,
- const IdType<TypeMarker, WrappedType, kInvalidValue>& id) {
- return stream << id.GetUnsafeValue();
-}
-
-} // namespace content
-
-namespace BASE_HASH_NAMESPACE {
-
-template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
-struct hash<content::IdType<TypeMarker, WrappedType, kInvalidValue>> {
- using argument_type = content::IdType<TypeMarker, WrappedType, kInvalidValue>;
- using result_type = std::size_t;
- result_type operator()(const argument_type& id) const {
- return BASE_HASH_NAMESPACE::hash<WrappedType>()(id.GetUnsafeValue());
- }
-};
-
-} // namespace BASE_HASH_NAMESPACE
-
-#endif // CONTENT_COMMON_ID_TYPE_H_
diff --git a/chromium/content/common/id_type_unittest.cc b/chromium/content/common/id_type_unittest.cc
deleted file mode 100644
index aa596d4cdc3..00000000000
--- a/chromium/content/common/id_type_unittest.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2016 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 <limits>
-#include <map>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-#include "base/containers/hash_tables.h"
-#include "content/common/id_type.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-class Foo;
-using FooId = IdType<Foo, int, 0>;
-
-class Bar;
-using BarId = IdType<Bar, int, 0>;
-
-class AnotherIdMarker;
-class DerivedId : public IdType<AnotherIdMarker, int, 0> {
- public:
- explicit DerivedId(int unsafe_value)
- : IdType<AnotherIdMarker, int, 0>(unsafe_value) {}
-};
-
-} // namespace
-
-TEST(IdType, DefaultValueIsInvalid) {
- FooId foo_id;
- EXPECT_TRUE(foo_id.is_null());
-}
-
-TEST(IdType, NormalValueIsValid) {
- FooId foo_id = FooId::FromUnsafeValue(123);
- EXPECT_FALSE(foo_id.is_null());
-}
-
-TEST(IdType, OutputStreamTest) {
- FooId foo_id = FooId::FromUnsafeValue(123);
-
- std::ostringstream ss;
- ss << foo_id;
- EXPECT_EQ("123", ss.str());
-}
-
-TEST(IdType, IdType32) {
- IdType32<Foo> id;
-
- EXPECT_EQ(0, id.GetUnsafeValue());
- static_assert(sizeof(int32_t) == sizeof(id), "");
-}
-
-TEST(IdType, IdTypeU32) {
- IdTypeU32<Foo> id;
-
- EXPECT_EQ(0u, id.GetUnsafeValue());
- static_assert(sizeof(uint32_t) == sizeof(id), "");
-}
-
-TEST(IdType, IdType64) {
- IdType64<Foo> id;
-
- EXPECT_EQ(0, id.GetUnsafeValue());
- static_assert(sizeof(int64_t) == sizeof(id), "");
-}
-
-TEST(IdType, IdTypeU64) {
- IdTypeU64<Foo> id;
-
- EXPECT_EQ(0u, id.GetUnsafeValue());
- static_assert(sizeof(uint64_t) == sizeof(id), "");
-}
-
-TEST(IdType, DerivedClasses) {
- DerivedId derived_id(456);
-
- std::ostringstream ss;
- ss << derived_id;
- EXPECT_EQ("456", ss.str());
-
- std::map<DerivedId, std::string> ordered_map;
- ordered_map[derived_id] = "blah";
- EXPECT_EQ(ordered_map[derived_id], "blah");
-
- // TODO(lukasza): Enable std::unordered_map and base::hash_map for DerivedId.
- // Ideally this should be possible without having to repeat std::hash<...>
- // specialization for each derived class (but then SFINAE + std::enable_if +
- // std::is_base_of doesn't seem to work for std::hash because std::hash only
- // has a single template parameter?).
- // std::unordered_map<DerivedId, std::string> unordered_map;
- // unordered_map[derived_id] = "blah2";
- // EXPECT_EQ(unordered_map[derived_id], "blah2");
-}
-
-TEST(IdType, StaticAsserts) {
- static_assert(!std::is_constructible<FooId, int>::value,
- "Should be impossible to construct FooId from a raw integer.");
- static_assert(!std::is_convertible<int, FooId>::value,
- "Should be impossible to convert a raw integer into FooId.");
-
- static_assert(!std::is_constructible<FooId, BarId>::value,
- "Should be impossible to construct FooId from a BarId.");
- static_assert(!std::is_convertible<BarId, FooId>::value,
- "Should be impossible to convert a BarId into FooId.");
-
- // The presence of a custom default constructor means that FooId is not a
- // "trivial" class and therefore is not a POD type (unlike an int32_t).
- // At the same time FooId has almost all of the properties of a POD type:
- // - is "trivially copyable" (i.e. is memcpy-able),
- // - has "standard layout" (i.e. interops with things expecting C layout).
- // See http://stackoverflow.com/a/7189821 for more info about these
- // concepts.
- static_assert(std::is_standard_layout<FooId>::value,
- "FooId should have standard layout. "
- "See http://stackoverflow.com/a/7189821 for more info.");
- static_assert(sizeof(FooId) == sizeof(int),
- "FooId should be the same size as the raw integer it wraps.");
- // TODO(lukasza): Enable these once <type_traits> supports all the standard
- // C++11 equivalents (i.e. std::is_trivially_copyable instead of the
- // non-standard std::has_trivial_copy_assign).
- // static_assert(std::has_trivial_copy_constructor<FooId>::value,
- // "FooId should have a trivial copy constructor.");
- // static_assert(std::has_trivial_copy_assign<FooId>::value,
- // "FooId should have a trivial copy assignment operator.");
- // static_assert(std::has_trivial_destructor<FooId>::value,
- // "FooId should have a trivial destructor.");
-}
-
-class IdTypeSpecificValueTest : public ::testing::TestWithParam<int> {
- protected:
- FooId test_id() { return FooId::FromUnsafeValue(GetParam()); }
-
- FooId other_id() {
- if (GetParam() != std::numeric_limits<int>::max())
- return FooId::FromUnsafeValue(GetParam() + 1);
- else
- return FooId::FromUnsafeValue(std::numeric_limits<int>::min());
- }
-};
-
-TEST_P(IdTypeSpecificValueTest, ComparisonToSelf) {
- EXPECT_TRUE(test_id() == test_id());
- EXPECT_FALSE(test_id() != test_id());
- EXPECT_FALSE(test_id() < test_id());
-}
-
-TEST_P(IdTypeSpecificValueTest, ComparisonToOther) {
- EXPECT_FALSE(test_id() == other_id());
- EXPECT_TRUE(test_id() != other_id());
-}
-
-TEST_P(IdTypeSpecificValueTest, UnsafeValueRoundtrips) {
- int original_value = GetParam();
- FooId id = FooId::FromUnsafeValue(original_value);
- int final_value = id.GetUnsafeValue();
- EXPECT_EQ(original_value, final_value);
-}
-
-TEST_P(IdTypeSpecificValueTest, Copying) {
- FooId original = test_id();
-
- FooId copy_via_constructor(original);
- EXPECT_EQ(original, copy_via_constructor);
-
- FooId copy_via_assignment;
- copy_via_assignment = original;
- EXPECT_EQ(original, copy_via_assignment);
-}
-
-TEST_P(IdTypeSpecificValueTest, BaseHashmap) {
- base::hash_map<FooId, std::string> map;
-
- map[test_id()] = "test_id";
- map[other_id()] = "other_id";
-
- EXPECT_EQ(map[test_id()], "test_id");
- EXPECT_EQ(map[other_id()], "other_id");
-}
-
-TEST_P(IdTypeSpecificValueTest, StdMap) {
- std::map<FooId, std::string> map;
-
- map[test_id()] = "test_id";
- map[other_id()] = "other_id";
-
- EXPECT_EQ(map[test_id()], "test_id");
- EXPECT_EQ(map[other_id()], "other_id");
-}
-
-INSTANTIATE_TEST_CASE_P(,
- IdTypeSpecificValueTest,
- ::testing::Values(std::numeric_limits<int>::min(),
- -1,
- 0,
- 1,
- 123,
- std::numeric_limits<int>::max()));
-
-} // namespace content
diff --git a/chromium/content/common/image_downloader/image_downloader.mojom b/chromium/content/common/image_downloader/image_downloader.mojom
index 7f3d289949d..b6ea34edd25 100644
--- a/chromium/content/common/image_downloader/image_downloader.mojom
+++ b/chromium/content/common/image_downloader/image_downloader.mojom
@@ -2,27 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module image_downloader;
+module content.mojom;
import "skia/public/interfaces/bitmap.mojom";
import "ui/mojo/geometry/geometry.mojom";
-struct DownloadRequest {
- string url;
- bool is_favicon;
- uint32 max_bitmap_size;
- bool bypass_cache;
-};
-
-struct DownloadResult {
- int32 http_status_code;
- array<skia.Bitmap> images;
- array<mojo.Size> original_image_sizes;
-};
-
interface ImageDownloader {
// Fetch and decode an image from a given URL.
// Returns the decoded images, or http_status_code to indicate error.
// Each call is independent, overlapping calls are possible.
- DownloadImage(DownloadRequest request) => (DownloadResult result);
+ DownloadImage(string url,
+ bool is_favicon,
+ uint32 max_bitmap_size,
+ bool bypass_cache)
+ => (int32 http_status_code,
+ array<skia.mojom.Bitmap> images,
+ array<mojo.Size> original_image_sizes);
};
diff --git a/chromium/content/common/in_process_child_thread_params.cc b/chromium/content/common/in_process_child_thread_params.cc
index 13e93902da6..84157997e06 100644
--- a/chromium/content/common/in_process_child_thread_params.cc
+++ b/chromium/content/common/in_process_child_thread_params.cc
@@ -8,9 +8,12 @@ namespace content {
InProcessChildThreadParams::InProcessChildThreadParams(
const std::string& channel_name,
- scoped_refptr<base::SequencedTaskRunner> io_runner)
- : channel_name_(channel_name), io_runner_(io_runner) {
-}
+ scoped_refptr<base::SequencedTaskRunner> io_runner,
+ mojo::MessagePipeHandle handle)
+ : channel_name_(channel_name), io_runner_(io_runner), handle_(handle) {}
+
+InProcessChildThreadParams::InProcessChildThreadParams(
+ const InProcessChildThreadParams& other) = default;
InProcessChildThreadParams::~InProcessChildThreadParams() {
}
diff --git a/chromium/content/common/in_process_child_thread_params.h b/chromium/content/common/in_process_child_thread_params.h
index 938a6ef0806..73838db02d5 100644
--- a/chromium/content/common/in_process_child_thread_params.h
+++ b/chromium/content/common/in_process_child_thread_params.h
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "content/common/content_export.h"
+#include "mojo/public/cpp/system/message_pipe.h"
namespace content {
@@ -20,17 +21,21 @@ class CONTENT_EXPORT InProcessChildThreadParams {
public:
InProcessChildThreadParams(
const std::string& channel_name,
- scoped_refptr<base::SequencedTaskRunner> io_runner);
+ scoped_refptr<base::SequencedTaskRunner> io_runner,
+ mojo::MessagePipeHandle handle = mojo::MessagePipeHandle());
+ InProcessChildThreadParams(const InProcessChildThreadParams& other);
~InProcessChildThreadParams();
const std::string& channel_name() const { return channel_name_; }
scoped_refptr<base::SequencedTaskRunner> io_runner() const {
return io_runner_;
}
+ mojo::MessagePipeHandle handle() const { return handle_; }
private:
std::string channel_name_;
scoped_refptr<base::SequencedTaskRunner> io_runner_;
+ mojo::MessagePipeHandle handle_;
};
} // namespace content
diff --git a/chromium/content/common/indexed_db/indexed_db_messages.h b/chromium/content/common/indexed_db/indexed_db_messages.h
index d360454f499..f0ec336ad9c 100644
--- a/chromium/content/common/indexed_db/indexed_db_messages.h
+++ b/chromium/content/common/indexed_db/indexed_db_messages.h
@@ -47,8 +47,8 @@ IPC_STRUCT_BEGIN(IndexedDBHostMsg_FactoryGetDatabaseNames_Params)
// The response should have these ids.
IPC_STRUCT_MEMBER(int32_t, ipc_thread_id)
IPC_STRUCT_MEMBER(int32_t, ipc_callbacks_id)
- // The string id of the origin doing the initiating.
- IPC_STRUCT_MEMBER(std::string, database_identifier)
+ // The origin doing the initiating.
+ IPC_STRUCT_MEMBER(GURL, origin)
IPC_STRUCT_END()
// Used to open an indexed database.
@@ -59,8 +59,8 @@ IPC_STRUCT_BEGIN(IndexedDBHostMsg_FactoryOpen_Params)
IPC_STRUCT_MEMBER(int32_t, ipc_callbacks_id)
// Identifier for database callbacks
IPC_STRUCT_MEMBER(int32_t, ipc_database_callbacks_id)
- // The string id of the origin doing the initiating.
- IPC_STRUCT_MEMBER(std::string, database_identifier)
+ // The origin doing the initiating.
+ IPC_STRUCT_MEMBER(GURL, origin)
// The name of the database.
IPC_STRUCT_MEMBER(base::string16, name)
// The transaction id used if a database upgrade is needed.
@@ -74,8 +74,8 @@ IPC_STRUCT_BEGIN(IndexedDBHostMsg_FactoryDeleteDatabase_Params)
// The response should have these ids.
IPC_STRUCT_MEMBER(int32_t, ipc_thread_id)
IPC_STRUCT_MEMBER(int32_t, ipc_callbacks_id)
- // The string id of the origin doing the initiating.
- IPC_STRUCT_MEMBER(std::string, database_identifier)
+ // The origin doing the initiating.
+ IPC_STRUCT_MEMBER(GURL, origin)
// The name of the database.
IPC_STRUCT_MEMBER(base::string16, name)
IPC_STRUCT_END()
@@ -341,8 +341,7 @@ IPC_STRUCT_END()
IPC_STRUCT_BEGIN(IndexedDBDatabaseMetadata)
IPC_STRUCT_MEMBER(int64_t, id)
IPC_STRUCT_MEMBER(base::string16, name)
- IPC_STRUCT_MEMBER(base::string16, version)
- IPC_STRUCT_MEMBER(int64_t, int_version)
+ IPC_STRUCT_MEMBER(int64_t, version)
IPC_STRUCT_MEMBER(int64_t, max_object_store_id)
IPC_STRUCT_MEMBER(std::vector<IndexedDBObjectStoreMetadata>, object_stores)
IPC_STRUCT_END()
@@ -424,7 +423,7 @@ IPC_MESSAGE_CONTROL1(IndexedDBMsg_CallbacksUpgradeNeeded,
IPC_MESSAGE_CONTROL2(IndexedDBMsg_DatabaseCallbacksForcedClose,
int32_t, /* ipc_thread_id */
int32_t) /* ipc_database_callbacks_id */
-IPC_MESSAGE_CONTROL4(IndexedDBMsg_DatabaseCallbacksIntVersionChange,
+IPC_MESSAGE_CONTROL4(IndexedDBMsg_DatabaseCallbacksVersionChange,
int32_t, /* ipc_thread_id */
int32_t, /* ipc_database_callbacks_id */
int64_t, /* old_version */
diff --git a/chromium/content/common/indexed_db/indexed_db_param_traits.cc b/chromium/content/common/indexed_db/indexed_db_param_traits.cc
index 9ca0ceceeac..c684e9f24d7 100644
--- a/chromium/content/common/indexed_db/indexed_db_param_traits.cc
+++ b/chromium/content/common/indexed_db/indexed_db_param_traits.cc
@@ -30,7 +30,7 @@ using blink::WebIDBKeyTypeString;
namespace IPC {
-void ParamTraits<IndexedDBKey>::Write(Message* m, const param_type& p) {
+void ParamTraits<IndexedDBKey>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, static_cast<int>(p.type()));
switch (p.type()) {
case WebIDBKeyTypeArray:
@@ -58,7 +58,7 @@ void ParamTraits<IndexedDBKey>::Write(Message* m, const param_type& p) {
}
}
-bool ParamTraits<IndexedDBKey>::Read(const Message* m,
+bool ParamTraits<IndexedDBKey>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
int type;
@@ -153,7 +153,8 @@ void ParamTraits<IndexedDBKey>::Log(const param_type& p, std::string* l) {
l->append(")");
}
-void ParamTraits<IndexedDBKeyPath>::Write(Message* m, const param_type& p) {
+void ParamTraits<IndexedDBKeyPath>::Write(base::Pickle* m,
+ const param_type& p) {
WriteParam(m, static_cast<int>(p.type()));
switch (p.type()) {
case WebIDBKeyPathTypeArray:
@@ -170,7 +171,7 @@ void ParamTraits<IndexedDBKeyPath>::Write(Message* m, const param_type& p) {
}
}
-bool ParamTraits<IndexedDBKeyPath>::Read(const Message* m,
+bool ParamTraits<IndexedDBKeyPath>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
int type;
@@ -230,14 +231,15 @@ void ParamTraits<IndexedDBKeyPath>::Log(const param_type& p, std::string* l) {
l->append(")");
}
-void ParamTraits<IndexedDBKeyRange>::Write(Message* m, const param_type& p) {
+void ParamTraits<IndexedDBKeyRange>::Write(base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.lower());
WriteParam(m, p.upper());
WriteParam(m, p.lower_open());
WriteParam(m, p.upper_open());
}
-bool ParamTraits<IndexedDBKeyRange>::Read(const Message* m,
+bool ParamTraits<IndexedDBKeyRange>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
IndexedDBKey lower;
diff --git a/chromium/content/common/indexed_db/indexed_db_param_traits.h b/chromium/content/common/indexed_db/indexed_db_param_traits.h
index 8f6eeb20bee..e11b2830743 100644
--- a/chromium/content/common/indexed_db/indexed_db_param_traits.h
+++ b/chromium/content/common/indexed_db/indexed_db_param_traits.h
@@ -21,24 +21,30 @@ namespace IPC {
template <>
struct ParamTraits<content::IndexedDBKey> {
typedef content::IndexedDBKey param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<content::IndexedDBKeyRange> {
typedef content::IndexedDBKeyRange param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<content::IndexedDBKeyPath> {
typedef content::IndexedDBKeyPath param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
diff --git a/chromium/content/common/input/event_with_latency_info.h b/chromium/content/common/input/event_with_latency_info.h
new file mode 100644
index 00000000000..24742a3baeb
--- /dev/null
+++ b/chromium/content/common/input/event_with_latency_info.h
@@ -0,0 +1,63 @@
+// Copyright 2013 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 CONTENT_COMMON_INPUT_EVENT_WITH_LATENCY_INFO_H_
+#define CONTENT_COMMON_INPUT_EVENT_WITH_LATENCY_INFO_H_
+
+#include "ui/events/latency_info.h"
+
+#include "content/common/input/web_input_event_traits.h"
+
+namespace blink {
+class WebGestureEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+class WebTouchEvent;
+}
+
+namespace content {
+
+template <typename T>
+class EventWithLatencyInfo {
+ public:
+ T event;
+ mutable ui::LatencyInfo latency;
+
+ explicit EventWithLatencyInfo(const T& e) : event(e) {}
+
+ EventWithLatencyInfo(const T& e, const ui::LatencyInfo& l)
+ : event(e), latency(l) {}
+
+ EventWithLatencyInfo() {}
+
+ bool CanCoalesceWith(const EventWithLatencyInfo& other)
+ const WARN_UNUSED_RESULT {
+ return WebInputEventTraits::CanCoalesce(other.event, event);
+ }
+
+ void CoalesceWith(const EventWithLatencyInfo& other) {
+ // |other| should be a newer event than |this|.
+ if (other.latency.trace_id() >= 0 && latency.trace_id() >= 0)
+ DCHECK_GT(other.latency.trace_id(), latency.trace_id());
+ WebInputEventTraits::Coalesce(other.event, &event);
+ // When coalescing two input events, we keep the oldest LatencyInfo
+ // for Telemetry latency tests, since it will represent the longest
+ // latency.
+ other.latency = latency;
+ other.latency.set_coalesced();
+ }
+};
+
+typedef EventWithLatencyInfo<blink::WebGestureEvent>
+ GestureEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebMouseWheelEvent>
+ MouseWheelEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebMouseEvent>
+ MouseEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebTouchEvent>
+ TouchEventWithLatencyInfo;
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_EVENT_WITH_LATENCY_INFO_H_
diff --git a/chromium/content/common/input/event_with_latency_info_unittest.cc b/chromium/content/common/input/event_with_latency_info_unittest.cc
new file mode 100644
index 00000000000..8ae533dd605
--- /dev/null
+++ b/chromium/content/common/input/event_with_latency_info_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2015 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 "content/common/input/event_with_latency_info.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+using blink::WebGestureEvent;
+using blink::WebInputEvent;
+using blink::WebMouseEvent;
+using blink::WebMouseWheelEvent;
+using blink::WebTouchEvent;
+
+namespace content {
+namespace {
+
+class EventWithLatencyInfoTest : public testing::Test {
+ protected:
+ TouchEventWithLatencyInfo CreateTouchEvent(WebInputEvent::Type type,
+ double timestamp) {
+ TouchEventWithLatencyInfo touch;
+ touch.event.touchesLength = 1;
+ touch.event.type = type;
+ touch.event.timeStampSeconds = timestamp;
+ return touch;
+ }
+
+ MouseEventWithLatencyInfo CreateMouseEvent(WebInputEvent::Type type,
+ double timestamp) {
+ MouseEventWithLatencyInfo mouse;
+ mouse.event.type = type;
+ mouse.event.timeStampSeconds = timestamp;
+ return mouse;
+ }
+
+ MouseWheelEventWithLatencyInfo CreateMouseWheelEvent(double timestamp) {
+ MouseWheelEventWithLatencyInfo mouse_wheel;
+ mouse_wheel.event.type = WebInputEvent::MouseWheel;
+ mouse_wheel.event.timeStampSeconds = timestamp;
+ return mouse_wheel;
+ }
+
+ GestureEventWithLatencyInfo CreateGestureEvent(WebInputEvent::Type type,
+ double timestamp) {
+ GestureEventWithLatencyInfo gesture;
+ gesture.event.type = type;
+ gesture.event.timeStampSeconds = timestamp;
+ return gesture;
+ }
+};
+
+TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForMouseEvent) {
+ MouseEventWithLatencyInfo mouse_0 = CreateMouseEvent(
+ WebInputEvent::MouseMove, 5.0);
+ MouseEventWithLatencyInfo mouse_1 = CreateMouseEvent(
+ WebInputEvent::MouseMove, 10.0);
+
+ ASSERT_TRUE(mouse_0.CanCoalesceWith(mouse_1));
+ mouse_0.CoalesceWith(mouse_1);
+ // Coalescing WebMouseEvent preserves newer timestamp.
+ EXPECT_EQ(10.0, mouse_0.event.timeStampSeconds);
+}
+
+TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForMouseWheelEvent) {
+ MouseWheelEventWithLatencyInfo mouse_wheel_0 = CreateMouseWheelEvent(5.0);
+ MouseWheelEventWithLatencyInfo mouse_wheel_1 = CreateMouseWheelEvent(10.0);
+
+ ASSERT_TRUE(mouse_wheel_0.CanCoalesceWith(mouse_wheel_1));
+ mouse_wheel_0.CoalesceWith(mouse_wheel_1);
+ // Coalescing WebMouseWheelEvent preserves newer timestamp.
+ EXPECT_EQ(10.0, mouse_wheel_0.event.timeStampSeconds);
+}
+
+TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForTouchEvent) {
+ TouchEventWithLatencyInfo touch_0 = CreateTouchEvent(
+ WebInputEvent::TouchMove, 5.0);
+ TouchEventWithLatencyInfo touch_1 = CreateTouchEvent(
+ WebInputEvent::TouchMove, 10.0);
+
+ ASSERT_TRUE(touch_0.CanCoalesceWith(touch_1));
+ touch_0.CoalesceWith(touch_1);
+ // Coalescing WebTouchEvent preserves newer timestamp.
+ EXPECT_EQ(10.0, touch_0.event.timeStampSeconds);
+}
+
+TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForGestureEvent) {
+ GestureEventWithLatencyInfo scroll_0 = CreateGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 5.0);
+ GestureEventWithLatencyInfo scroll_1 = CreateGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 10.0);
+
+ ASSERT_TRUE(scroll_0.CanCoalesceWith(scroll_1));
+ scroll_0.CoalesceWith(scroll_1);
+ // Coalescing WebGestureEvent preserves newer timestamp.
+ EXPECT_EQ(10.0, scroll_0.event.timeStampSeconds);
+}
+
+TEST_F(EventWithLatencyInfoTest, LatencyInfoCoalescing) {
+ MouseEventWithLatencyInfo mouse_0 = CreateMouseEvent(
+ WebInputEvent::MouseMove, 5.0);
+ mouse_0.latency.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, base::TimeTicks(), 1);
+ MouseEventWithLatencyInfo mouse_1 = CreateMouseEvent(
+ WebInputEvent::MouseMove, 10.0);
+
+ ASSERT_TRUE(mouse_0.CanCoalesceWith(mouse_1));
+
+ ui::LatencyInfo::LatencyComponent component;
+ EXPECT_FALSE(mouse_1.latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component));
+
+ mouse_0.CoalesceWith(mouse_1);
+
+ // Coalescing WebMouseEvent preservers older LatencyInfo.
+ EXPECT_TRUE(mouse_1.latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component));
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/common/input/input_event_ack_state.h b/chromium/content/common/input/input_event_ack_state.h
index 5b9c706e6b4..c8e8f833b86 100644
--- a/chromium/content/common/input/input_event_ack_state.h
+++ b/chromium/content/common/input/input_event_ack_state.h
@@ -14,7 +14,8 @@ enum InputEventAckState {
INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
INPUT_EVENT_ACK_STATE_IGNORED,
- INPUT_EVENT_ACK_STATE_MAX = INPUT_EVENT_ACK_STATE_IGNORED
+ INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING,
+ INPUT_EVENT_ACK_STATE_MAX = INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING
};
} // namespace content
diff --git a/chromium/content/common/input/input_event_dispatch_type.h b/chromium/content/common/input/input_event_dispatch_type.h
new file mode 100644
index 00000000000..ea802ff2c81
--- /dev/null
+++ b/chromium/content/common/input/input_event_dispatch_type.h
@@ -0,0 +1,26 @@
+// Copyright 2016 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 CONTENT_COMMON_INPUT_INPUT_EVENT_DISPATCH_TYPE_H_
+#define CONTENT_COMMON_INPUT_INPUT_EVENT_DISPATCH_TYPE_H_
+
+namespace content {
+
+enum InputEventDispatchType {
+ // Dispatch a blocking event. Sender is waiting on an ACK.
+ DISPATCH_TYPE_BLOCKING,
+ // Dispatch a blocking event and notify main thread as well. This type
+ // should only be sent from the compositor to main thread.
+ DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN,
+ // Dispatch a non-blocking event. Sender will not receive an ACK.
+ DISPATCH_TYPE_NON_BLOCKING,
+ // Dispatch a non-blocking event and notify main thread as well. This type
+ // should only be sent from the compositor to main thread.
+ DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN,
+ DISPATCH_TYPE_MAX = DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_INPUT_EVENT_DISPATCH_TYPE_H_
diff --git a/chromium/content/common/input/input_event_utils.cc b/chromium/content/common/input/input_event_utils.cc
new file mode 100644
index 00000000000..31669ed3ca3
--- /dev/null
+++ b/chromium/content/common/input/input_event_utils.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 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 "content/common/input/input_event_utils.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+bool UseGestureBasedWheelScrolling() {
+ base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
+ return !cmd->HasSwitch(switches::kDisableWheelGestures);
+}
+
+} // namespace content
diff --git a/chromium/content/common/input/input_event_utils.h b/chromium/content/common/input/input_event_utils.h
new file mode 100644
index 00000000000..c1a61ce2444
--- /dev/null
+++ b/chromium/content/common/input/input_event_utils.h
@@ -0,0 +1,17 @@
+// Copyright 2016 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 CONTENT_RENDERER_INPUT_INPUT_EVENT_UTILS_H_
+#define CONTENT_RENDERER_INPUT_INPUT_EVENT_UTILS_H_
+
+#include "content/common/content_export.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+CONTENT_EXPORT bool UseGestureBasedWheelScrolling();
+
+}; // namespace content
+
+#endif // CONTENT_RENDERER_INPUT_INPUT_EVENT_UTILS_H_
diff --git a/chromium/content/common/input/input_param_traits.cc b/chromium/content/common/input/input_param_traits.cc
index 0402f433c5e..076d54ace06 100644
--- a/chromium/content/common/input/input_param_traits.cc
+++ b/chromium/content/common/input/input_param_traits.cc
@@ -8,6 +8,7 @@
#include "content/common/content_param_traits.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
+#include "content/common/input/synthetic_pointer_action_params.h"
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/web_input_event_traits.h"
@@ -17,7 +18,7 @@ namespace IPC {
namespace {
template <typename GestureType>
scoped_ptr<content::SyntheticGestureParams> ReadGestureParams(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter) {
scoped_ptr<GestureType> gesture_params(new GestureType);
if (!ReadParam(m, iter, gesture_params.get()))
@@ -27,7 +28,7 @@ scoped_ptr<content::SyntheticGestureParams> ReadGestureParams(
}
} // namespace
-void ParamTraits<content::ScopedWebInputEvent>::Write(Message* m,
+void ParamTraits<content::ScopedWebInputEvent>::Write(base::Pickle* m,
const param_type& p) {
bool valid_web_event = !!p;
WriteParam(m, valid_web_event);
@@ -35,7 +36,7 @@ void ParamTraits<content::ScopedWebInputEvent>::Write(Message* m,
WriteParam(m, static_cast<WebInputEventPointer>(p.get()));
}
-bool ParamTraits<content::ScopedWebInputEvent>::Read(const Message* m,
+bool ParamTraits<content::ScopedWebInputEvent>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
bool valid_web_event = false;
@@ -55,7 +56,7 @@ void ParamTraits<content::ScopedWebInputEvent>::Log(const param_type& p,
LogParam(static_cast<WebInputEventPointer>(p.get()), l);
}
-void ParamTraits<content::SyntheticGesturePacket>::Write(Message* m,
+void ParamTraits<content::SyntheticGesturePacket>::Write(base::Pickle* m,
const param_type& p) {
DCHECK(p.gesture_params());
WriteParam(m, p.gesture_params()->GetGestureType());
@@ -76,11 +77,15 @@ void ParamTraits<content::SyntheticGesturePacket>::Write(Message* m,
WriteParam(m, *content::SyntheticTapGestureParams::Cast(
p.gesture_params()));
break;
+ case content::SyntheticGestureParams::POINTER_ACTION:
+ WriteParam(
+ m, *content::SyntheticPointerActionParams::Cast(p.gesture_params()));
+ break;
}
}
bool ParamTraits<content::SyntheticGesturePacket>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
content::SyntheticGestureParams::GestureType gesture_type;
@@ -105,6 +110,11 @@ bool ParamTraits<content::SyntheticGesturePacket>::Read(
gesture_params =
ReadGestureParams<content::SyntheticTapGestureParams>(m, iter);
break;
+ case content::SyntheticGestureParams::POINTER_ACTION: {
+ gesture_params =
+ ReadGestureParams<content::SyntheticPointerActionParams>(m, iter);
+ break;
+ }
default:
return false;
}
@@ -138,6 +148,10 @@ void ParamTraits<content::SyntheticGesturePacket>::Log(const param_type& p,
*content::SyntheticTapGestureParams::Cast(p.gesture_params()),
l);
break;
+ case content::SyntheticGestureParams::POINTER_ACTION:
+ LogParam(*content::SyntheticPointerActionParams::Cast(p.gesture_params()),
+ l);
+ break;
}
}
diff --git a/chromium/content/common/input/input_param_traits.h b/chromium/content/common/input/input_param_traits.h
index 9f5b1cec36c..1c204c3bc31 100644
--- a/chromium/content/common/input/input_param_traits.h
+++ b/chromium/content/common/input/input_param_traits.h
@@ -18,16 +18,20 @@ namespace IPC {
template <>
struct CONTENT_EXPORT ParamTraits<content::ScopedWebInputEvent> {
typedef content::ScopedWebInputEvent param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template<>
struct CONTENT_EXPORT ParamTraits<content::SyntheticGesturePacket> {
typedef content::SyntheticGesturePacket param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
diff --git a/chromium/content/common/input/input_param_traits_unittest.cc b/chromium/content/common/input/input_param_traits_unittest.cc
index 0dd2b3d1441..1935f9ca945 100644
--- a/chromium/content/common/input/input_param_traits_unittest.cc
+++ b/chromium/content/common/input/input_param_traits_unittest.cc
@@ -10,6 +10,7 @@
#include "content/common/input/input_event.h"
#include "content/common/input/synthetic_gesture_params.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
+#include "content/common/input/synthetic_pointer_action_params.h"
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input_messages.h"
@@ -77,6 +78,22 @@ class InputParamTraitsTest : public testing::Test {
EXPECT_EQ(a->duration_ms, b->duration_ms);
}
+ static void Compare(const SyntheticPointerActionParams* a,
+ const SyntheticPointerActionParams* b) {
+ EXPECT_EQ(a->gesture_source_type, b->gesture_source_type);
+ EXPECT_EQ(a->pointer_action_type(), b->pointer_action_type());
+ if (a->pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::PRESS ||
+ a->pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::MOVE) {
+ EXPECT_EQ(a->position(), b->position());
+ }
+ if (a->pointer_action_type() !=
+ SyntheticPointerActionParams::PointerActionType::PROCESS) {
+ EXPECT_EQ(a->index(), b->index());
+ }
+ }
+
static void Compare(const SyntheticGesturePacket* a,
const SyntheticGesturePacket* b) {
ASSERT_EQ(!!a, !!b);
@@ -102,6 +119,10 @@ class InputParamTraitsTest : public testing::Test {
Compare(SyntheticTapGestureParams::Cast(a->gesture_params()),
SyntheticTapGestureParams::Cast(b->gesture_params()));
break;
+ case SyntheticGestureParams::POINTER_ACTION:
+ Compare(SyntheticPointerActionParams::Cast(a->gesture_params()),
+ SyntheticPointerActionParams::Cast(b->gesture_params()));
+ break;
}
}
@@ -250,5 +271,44 @@ TEST_F(InputParamTraitsTest, SyntheticTapGestureParams) {
Verify(packet_in);
}
+TEST_F(InputParamTraitsTest, SyntheticPointerActionParamsMove) {
+ scoped_ptr<SyntheticPointerActionParams> gesture_params(
+ new SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::MOVE));
+ gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ gesture_params->set_position(gfx::PointF(356, 287));
+ gesture_params->set_index(0);
+ ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION,
+ gesture_params->GetGestureType());
+ SyntheticGesturePacket packet_in;
+ packet_in.set_gesture_params(std::move(gesture_params));
+ Verify(packet_in);
+}
+
+TEST_F(InputParamTraitsTest, SyntheticPointerActionParamsRelease) {
+ scoped_ptr<SyntheticPointerActionParams> gesture_params(
+ new SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::RELEASE));
+ gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ gesture_params->set_index(0);
+ ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION,
+ gesture_params->GetGestureType());
+ SyntheticGesturePacket packet_in;
+ packet_in.set_gesture_params(std::move(gesture_params));
+ Verify(packet_in);
+}
+
+TEST_F(InputParamTraitsTest, SyntheticPointerActionParamsProcess) {
+ scoped_ptr<SyntheticPointerActionParams> gesture_params(
+ new SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::PROCESS));
+ gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION,
+ gesture_params->GetGestureType());
+ SyntheticGesturePacket packet_in;
+ packet_in.set_gesture_params(std::move(gesture_params));
+ Verify(packet_in);
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/common/input/synthetic_gesture_params.h b/chromium/content/common/input/synthetic_gesture_params.h
index 1c40ca98fd2..5ece4db2996 100644
--- a/chromium/content/common/input/synthetic_gesture_params.h
+++ b/chromium/content/common/input/synthetic_gesture_params.h
@@ -48,8 +48,10 @@ struct CONTENT_EXPORT SyntheticGestureParams {
SMOOTH_DRAG_GESTURE,
PINCH_GESTURE,
TAP_GESTURE,
- SYNTHETIC_GESTURE_TYPE_MAX = TAP_GESTURE
+ POINTER_ACTION,
+ SYNTHETIC_GESTURE_TYPE_MAX = POINTER_ACTION
};
+
virtual GestureType GetGestureType() const = 0;
// Returns true if the specific gesture source type is supported on this
diff --git a/chromium/content/common/input/synthetic_pointer_action_params.cc b/chromium/content/common/input/synthetic_pointer_action_params.cc
new file mode 100644
index 00000000000..593413b9822
--- /dev/null
+++ b/chromium/content/common/input/synthetic_pointer_action_params.cc
@@ -0,0 +1,48 @@
+// Copyright 2016 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 "content/common/input/synthetic_pointer_action_params.h"
+
+namespace content {
+
+SyntheticPointerActionParams::SyntheticPointerActionParams()
+ : pointer_action_type_(PointerActionType::NOT_INITIALIZED), index_(-1) {}
+
+SyntheticPointerActionParams::SyntheticPointerActionParams(
+ PointerActionType type)
+ : pointer_action_type_(type), index_(-1) {}
+
+SyntheticPointerActionParams::SyntheticPointerActionParams(
+ const SyntheticPointerActionParams& other)
+ : SyntheticGestureParams(other),
+ pointer_action_type_(other.pointer_action_type()) {
+ switch (other.pointer_action_type()) {
+ case PointerActionType::PRESS:
+ case PointerActionType::MOVE:
+ index_ = other.index();
+ position_ = other.position();
+ break;
+ case PointerActionType::RELEASE:
+ index_ = other.index();
+ break;
+ default:
+ break;
+ }
+}
+
+SyntheticPointerActionParams::~SyntheticPointerActionParams() {}
+
+SyntheticGestureParams::GestureType
+SyntheticPointerActionParams::GetGestureType() const {
+ return POINTER_ACTION;
+}
+
+const SyntheticPointerActionParams* SyntheticPointerActionParams::Cast(
+ const SyntheticGestureParams* gesture_params) {
+ DCHECK(gesture_params);
+ DCHECK_EQ(POINTER_ACTION, gesture_params->GetGestureType());
+ return static_cast<const SyntheticPointerActionParams*>(gesture_params);
+}
+
+} // namespace content
diff --git a/chromium/content/common/input/synthetic_pointer_action_params.h b/chromium/content/common/input/synthetic_pointer_action_params.h
new file mode 100644
index 00000000000..fe6c9f9b4a3
--- /dev/null
+++ b/chromium/content/common/input/synthetic_pointer_action_params.h
@@ -0,0 +1,86 @@
+// Copyright 2016 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 CONTENT_COMMON_INPUT_SYNTHETIC_POINTER_ACTION_PARAMS_H_
+#define CONTENT_COMMON_INPUT_SYNTHETIC_POINTER_ACTION_PARAMS_H_
+
+#include "base/logging.h"
+#include "content/common/content_export.h"
+#include "content/common/input/input_param_traits.h"
+#include "content/common/input/synthetic_gesture_params.h"
+#include "ui/gfx/geometry/point_f.h"
+
+namespace ipc_fuzzer {
+template <class T>
+struct FuzzTraits;
+} // namespace ipc_fuzzer
+
+namespace content {
+
+struct CONTENT_EXPORT SyntheticPointerActionParams
+ : public SyntheticGestureParams {
+ public:
+ // Actions are queued up until we receive a PROCESS action, at which point
+ // we'll dispatch all queued events.
+ enum class PointerActionType {
+ NOT_INITIALIZED,
+ PRESS,
+ MOVE,
+ RELEASE,
+ PROCESS,
+ POINTER_ACTION_TYPE_MAX = PROCESS
+ };
+
+ SyntheticPointerActionParams();
+ explicit SyntheticPointerActionParams(PointerActionType type);
+ SyntheticPointerActionParams(const SyntheticPointerActionParams& other);
+ ~SyntheticPointerActionParams() override;
+
+ GestureType GetGestureType() const override;
+
+ static const SyntheticPointerActionParams* Cast(
+ const SyntheticGestureParams* gesture_params);
+
+ void set_pointer_action_type(PointerActionType pointer_action_type) {
+ pointer_action_type_ = pointer_action_type;
+ }
+
+ void set_index(int index) {
+ DCHECK(pointer_action_type_ != PointerActionType::PROCESS);
+ index_ = index;
+ }
+
+ void set_position(const gfx::PointF& position) {
+ DCHECK(pointer_action_type_ == PointerActionType::PRESS ||
+ pointer_action_type_ == PointerActionType::MOVE);
+ position_ = position;
+ }
+
+ PointerActionType pointer_action_type() const { return pointer_action_type_; }
+
+ int index() const {
+ DCHECK(pointer_action_type_ != PointerActionType::PROCESS);
+ return index_;
+ }
+
+ gfx::PointF position() const {
+ DCHECK(pointer_action_type_ == PointerActionType::PRESS ||
+ pointer_action_type_ == PointerActionType::MOVE);
+ return position_;
+ }
+
+ private:
+ friend struct IPC::ParamTraits<content::SyntheticPointerActionParams>;
+ friend struct ipc_fuzzer::FuzzTraits<content::SyntheticPointerActionParams>;
+
+ PointerActionType pointer_action_type_;
+ // Pass a position value when sending a press or move action.
+ gfx::PointF position_;
+ // Pass an index value except if the pointer_action_type_ is PROCESS.
+ int index_;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_SYNTHETIC_POINTER_ACTION_PARAMS_H_
diff --git a/chromium/content/common/input/synthetic_web_input_event_builders.cc b/chromium/content/common/input/synthetic_web_input_event_builders.cc
index e2e17febb95..c68c689c09b 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.cc
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.cc
@@ -61,8 +61,21 @@ WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(float x,
float dy,
int modifiers,
bool precise) {
+ return Build(x, y, 0, 0, dx, dy, modifiers, precise);
+}
+
+WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(float x,
+ float y,
+ float global_x,
+ float global_y,
+ float dx,
+ float dy,
+ int modifiers,
+ bool precise) {
WebMouseWheelEvent result;
result.type = WebInputEvent::MouseWheel;
+ result.globalX = global_x;
+ result.globalY = global_y;
result.x = x;
result.y = y;
result.deltaX = dx;
@@ -171,7 +184,7 @@ void SyntheticWebTouchEvent::ResetPoints() {
}
touchesLength = point;
type = WebInputEvent::Undefined;
- causesScrollingIfUncanceled = false;
+ movedBeyondSlopRegion = false;
uniqueTouchEventId = ui::GetNextTouchEventId();
}
@@ -198,7 +211,7 @@ void SyntheticWebTouchEvent::MovePoint(int index, float x, float y) {
CHECK_LT(index, touchesLengthCap);
// Always set this bit to avoid otherwise unexpected touchmove suppression.
// The caller can opt-out explicitly, if necessary.
- causesScrollingIfUncanceled = true;
+ movedBeyondSlopRegion = true;
WebTouchPoint& point = touches[index];
point.position.x = point.screenPosition.x = x;
point.position.y = point.screenPosition.y = y;
diff --git a/chromium/content/common/input/synthetic_web_input_event_builders.h b/chromium/content/common/input/synthetic_web_input_event_builders.h
index ef1a1694bb7..e865e9b23ce 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.h
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.h
@@ -32,6 +32,14 @@ class CONTENT_EXPORT SyntheticWebMouseWheelEventBuilder {
float dy,
int modifiers,
bool precise);
+ static blink::WebMouseWheelEvent Build(float x,
+ float y,
+ float global_x,
+ float global_y,
+ float dx,
+ float dy,
+ int modifiers,
+ bool precise);
};
class CONTENT_EXPORT SyntheticWebKeyboardEventBuilder {
diff --git a/chromium/content/common/input/web_input_event_queue.h b/chromium/content/common/input/web_input_event_queue.h
new file mode 100644
index 00000000000..fa85bd4f773
--- /dev/null
+++ b/chromium/content/common/input/web_input_event_queue.h
@@ -0,0 +1,79 @@
+// Copyright 2016 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 CONTENT_COMMON_INPUT_WEB_INPUT_EVENT_QUEUE_H_
+#define CONTENT_COMMON_INPUT_WEB_INPUT_EVENT_QUEUE_H_
+
+#include <deque>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace content {
+
+enum class WebInputEventQueueState { ITEM_PENDING, ITEM_NOT_PENDING };
+
+// WebInputEventQueue is a coalescing queue with the addition of a state
+// variable that represents whether an item is pending to be processed.
+// The desired usage sending with this queue is:
+// if (queue.state() == WebInputEventQueueState::ITEM_PENDING) {
+// queue.Queue(T);
+// } else {
+// send T
+// queue.set_state(WebInputEventQueueState::ITEM_PENDING);
+// }
+//
+// Processing the event response:
+// if (!queue.empty()) {
+// T = queue.Pop();
+// send T now
+// } else {
+// queue.set_state(WebInputEventQueueState::ITEM_NOT_PENDING);
+// }
+//
+template <typename T>
+class WebInputEventQueue {
+ public:
+ WebInputEventQueue() : state_(WebInputEventQueueState::ITEM_NOT_PENDING) {}
+
+ // Adds an event to the queue. The event may be coalesced with previously
+ // queued events.
+ void Queue(const T& event) {
+ if (!queue_.empty()) {
+ scoped_ptr<T>& last_event = queue_.back();
+ if (last_event->CanCoalesceWith(event)) {
+ last_event->CoalesceWith(event);
+ return;
+ }
+ }
+ queue_.emplace_back(scoped_ptr<T>(new T(event)));
+ }
+
+ scoped_ptr<T> Pop() {
+ scoped_ptr<T> result;
+ if (!queue_.empty()) {
+ result.reset(queue_.front().release());
+ queue_.pop_front();
+ }
+ return result;
+ }
+
+ bool empty() const { return queue_.empty(); }
+
+ size_t size() const { return queue_.size(); }
+
+ void set_state(WebInputEventQueueState state) { state_ = state; }
+
+ WebInputEventQueueState state() const WARN_UNUSED_RESULT { return state_; }
+
+ private:
+ typedef std::deque<scoped_ptr<T>> EventQueue;
+ EventQueue queue_;
+ WebInputEventQueueState state_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebInputEventQueue);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_WEB_INPUT_EVENT_QUEUE_H_
diff --git a/chromium/content/common/input/web_input_event_traits.cc b/chromium/content/common/input/web_input_event_traits.cc
index 1008c549ef6..3aed966c5b6 100644
--- a/chromium/content/common/input/web_input_event_traits.cc
+++ b/chromium/content/common/input/web_input_event_traits.cc
@@ -111,10 +111,10 @@ void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) {
void ApppendEventDetails(const WebTouchEvent& event, std::string* result) {
StringAppendF(result,
- "{\n Touches: %u, Cancelable: %d, CausesScrolling: %d,"
+ "{\n Touches: %u, DispatchType: %d, CausesScrolling: %d,"
" uniqueTouchEventId: %u\n[\n",
- event.touchesLength, event.cancelable,
- event.causesScrollingIfUncanceled, event.uniqueTouchEventId);
+ event.touchesLength, event.dispatchType,
+ event.movedBeyondSlopRegion, event.uniqueTouchEventId);
for (unsigned i = 0; i < event.touchesLength; ++i)
ApppendTouchPointDetails(event.touches[i], result);
result->append(" ]\n}");
@@ -199,6 +199,23 @@ int GetIndexOfTouchID(const WebTouchEvent& event, int id) {
return kInvalidTouchIndex;
}
+WebInputEvent::DispatchType MergeDispatchTypes(
+ WebInputEvent::DispatchType type_1,
+ WebInputEvent::DispatchType type_2) {
+ static_assert(WebInputEvent::DispatchType::Blocking <
+ WebInputEvent::DispatchType::EventNonBlocking,
+ "Enum not ordered correctly");
+ static_assert(WebInputEvent::DispatchType::EventNonBlocking <
+ WebInputEvent::DispatchType::ListenersNonBlockingPassive,
+ "Enum not ordered correctly");
+ static_assert(
+ WebInputEvent::DispatchType::ListenersNonBlockingPassive <
+ WebInputEvent::DispatchType::ListenersForcedNonBlockingPassive,
+ "Enum not ordered correctly");
+ return static_cast<WebInputEvent::DispatchType>(
+ std::min(static_cast<int>(type_1), static_cast<int>(type_2)));
+}
+
bool CanCoalesce(const WebTouchEvent& event_to_coalesce,
const WebTouchEvent& event) {
if (event.type != event_to_coalesce.type ||
@@ -240,7 +257,9 @@ void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) {
if (old_event.touches[i_old].state == blink::WebTouchPoint::StateMoved)
event->touches[i].state = blink::WebTouchPoint::StateMoved;
}
- event->causesScrollingIfUncanceled |= old_event.causesScrollingIfUncanceled;
+ event->movedBeyondSlopRegion |= old_event.movedBeyondSlopRegion;
+ event->dispatchType = MergeDispatchTypes(old_event.dispatchType,
+ event_to_coalesce.dispatchType);
}
bool CanCoalesce(const WebGestureEvent& event_to_coalesce,
@@ -466,8 +485,7 @@ void WebInputEventTraits::Coalesce(const WebInputEvent& event_to_coalesce,
Apply(WebInputEventCoalesce(), event->type, event_to_coalesce, event);
}
-bool WebInputEventTraits::WillReceiveAckFromRenderer(
- const WebInputEvent& event) {
+bool WebInputEventTraits::ShouldBlockEventStream(const WebInputEvent& event) {
switch (event.type) {
case WebInputEvent::MouseDown:
case WebInputEvent::MouseUp:
@@ -482,11 +500,24 @@ bool WebInputEventTraits::WillReceiveAckFromRenderer(
case WebInputEvent::GestureTapCancel:
case WebInputEvent::GesturePinchBegin:
case WebInputEvent::GesturePinchEnd:
+ return false;
+
+ // TouchCancel should always be non-blocking.
case WebInputEvent::TouchCancel:
+ DCHECK_NE(WebInputEvent::Blocking,
+ static_cast<const WebTouchEvent&>(event).dispatchType);
return false;
+
+ // Touch start and touch end indicate whether they are non-blocking
+ // (aka uncancelable) on the event.
case WebInputEvent::TouchStart:
case WebInputEvent::TouchEnd:
- return static_cast<const WebTouchEvent&>(event).cancelable;
+ return static_cast<const WebTouchEvent&>(event).dispatchType ==
+ WebInputEvent::Blocking;
+
+ // Touch move events may be non-blocking but are always explicitly
+ // acknowledge by the renderer so they block the event stream.
+ case WebInputEvent::TouchMove:
default:
return true;
}
diff --git a/chromium/content/common/input/web_input_event_traits.h b/chromium/content/common/input/web_input_event_traits.h
index 008439c9e28..2f9ca8c5232 100644
--- a/chromium/content/common/input/web_input_event_traits.h
+++ b/chromium/content/common/input/web_input_event_traits.h
@@ -27,7 +27,7 @@ class CONTENT_EXPORT WebInputEventTraits {
const blink::WebInputEvent& event);
static void Coalesce(const blink::WebInputEvent& event_to_coalesce,
blink::WebInputEvent* event);
- static bool WillReceiveAckFromRenderer(const blink::WebInputEvent& event);
+ static bool ShouldBlockEventStream(const blink::WebInputEvent& event);
// Return uniqueTouchEventId for WebTouchEvent, otherwise return 0.
static uint32_t GetUniqueTouchEventId(const blink::WebInputEvent& event);
diff --git a/chromium/content/common/input/web_input_event_traits_unittest.cc b/chromium/content/common/input/web_input_event_traits_unittest.cc
index 6ae3d936616..1daf80dcf1a 100644
--- a/chromium/content/common/input/web_input_event_traits_unittest.cc
+++ b/chromium/content/common/input/web_input_event_traits_unittest.cc
@@ -124,6 +124,34 @@ TEST_F(WebInputEventTraitsTest, TouchEventCoalescing) {
ASSERT_EQ(0, touch1.touches[1].id);
EXPECT_EQ(WebTouchPoint::StateMoved, touch1.touches[0].state);
EXPECT_EQ(WebTouchPoint::StateMoved, touch1.touches[1].state);
+
+ // Touch moves with different dispatchTypes coalesce.
+ touch0 = CreateTouch(WebInputEvent::TouchMove, 2);
+ touch0.dispatchType = WebInputEvent::DispatchType::Blocking;
+ touch1 = CreateTouch(WebInputEvent::TouchMove, 2);
+ touch1.dispatchType = WebInputEvent::DispatchType::EventNonBlocking;
+ touch0.touches[0] = touch1.touches[1] =
+ CreateTouchPoint(WebTouchPoint::StateMoved, 1);
+ touch0.touches[1] = touch1.touches[0] =
+ CreateTouchPoint(WebTouchPoint::StateMoved, 0);
+ EXPECT_TRUE(WebInputEventTraits::CanCoalesce(touch0, touch1));
+ WebInputEventTraits::Coalesce(touch0, &touch1);
+ ASSERT_EQ(WebInputEvent::DispatchType::Blocking, touch1.dispatchType);
+
+ touch0 = CreateTouch(WebInputEvent::TouchMove, 2);
+ touch0.dispatchType =
+ WebInputEvent::DispatchType::ListenersForcedNonBlockingPassive;
+ touch1 = CreateTouch(WebInputEvent::TouchMove, 2);
+ touch1.dispatchType =
+ WebInputEvent::DispatchType::ListenersNonBlockingPassive;
+ touch0.touches[0] = touch1.touches[1] =
+ CreateTouchPoint(WebTouchPoint::StateMoved, 1);
+ touch0.touches[1] = touch1.touches[0] =
+ CreateTouchPoint(WebTouchPoint::StateMoved, 0);
+ EXPECT_TRUE(WebInputEventTraits::CanCoalesce(touch0, touch1));
+ WebInputEventTraits::Coalesce(touch0, &touch1);
+ ASSERT_EQ(WebInputEvent::DispatchType::ListenersNonBlockingPassive,
+ touch1.dispatchType);
}
TEST_F(WebInputEventTraitsTest, PinchEventCoalescing) {
diff --git a/chromium/content/common/input/web_touch_event_traits.cc b/chromium/content/common/input/web_touch_event_traits.cc
index 175bf78ef41..77aa00f7069 100644
--- a/chromium/content/common/input/web_touch_event_traits.cc
+++ b/chromium/content/common/input/web_touch_event_traits.cc
@@ -52,7 +52,9 @@ void WebTouchEventTraits::ResetType(WebInputEvent::Type type,
WebTouchEvent* event) {
DCHECK(WebInputEvent::isTouchEventType(type));
event->type = type;
- event->cancelable = (type != WebInputEvent::TouchCancel);
+ event->dispatchType = type == WebInputEvent::TouchCancel
+ ? WebInputEvent::EventNonBlocking
+ : WebInputEvent::Blocking;
event->timeStampSeconds = timestamp_sec;
}
diff --git a/chromium/content/common/input_messages.h b/chromium/content/common/input_messages.h
index a511d018458..e83a77bac4e 100644
--- a/chromium/content/common/input_messages.h
+++ b/chromium/content/common/input_messages.h
@@ -15,15 +15,16 @@
#include "content/common/input/input_event.h"
#include "content/common/input/input_event_ack.h"
#include "content/common/input/input_event_ack_state.h"
+#include "content/common/input/input_event_dispatch_type.h"
#include "content/common/input/input_param_traits.h"
#include "content/common/input/synthetic_gesture_packet.h"
#include "content/common/input/synthetic_gesture_params.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
+#include "content/common/input/synthetic_pointer_action_params.h"
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
#include "content/common/input/touch_action.h"
-#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/ipc/latency_info_param_traits.h"
@@ -31,6 +32,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
#include "ui/gfx/range/range.h"
#undef IPC_MESSAGE_EXPORT
@@ -48,6 +50,12 @@ IPC_ENUM_TRAITS_MAX_VALUE(
IPC_ENUM_TRAITS_MAX_VALUE(
content::SyntheticGestureParams::GestureType,
content::SyntheticGestureParams::SYNTHETIC_GESTURE_TYPE_MAX)
+IPC_ENUM_TRAITS_MAX_VALUE(
+ content::SyntheticPointerActionParams::PointerActionType,
+ content::SyntheticPointerActionParams::PointerActionType::
+ POINTER_ACTION_TYPE_MAX)
+IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventDispatchType,
+ content::InputEventDispatchType::DISPATCH_TYPE_MAX)
IPC_ENUM_TRAITS_VALIDATE(content::TouchAction, (
value >= 0 &&
value <= content::TOUCH_ACTION_MAX &&
@@ -105,6 +113,13 @@ IPC_STRUCT_TRAITS_BEGIN(content::SyntheticTapGestureParams)
IPC_STRUCT_TRAITS_MEMBER(duration_ms)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(content::SyntheticPointerActionParams)
+ IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams)
+ IPC_STRUCT_TRAITS_MEMBER(pointer_action_type_)
+ IPC_STRUCT_TRAITS_MEMBER(index_)
+ IPC_STRUCT_TRAITS_MEMBER(position_)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::InputEventAck)
IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(state)
@@ -114,9 +129,10 @@ IPC_STRUCT_TRAITS_BEGIN(content::InputEventAck)
IPC_STRUCT_TRAITS_END()
// Sends an input event to the render widget.
-IPC_MESSAGE_ROUTED2(InputMsg_HandleInputEvent,
+IPC_MESSAGE_ROUTED3(InputMsg_HandleInputEvent,
IPC::WebInputEventPointer /* event */,
- ui::LatencyInfo /* latency_info */)
+ ui::LatencyInfo /* latency_info */,
+ content::InputEventDispatchType)
// Sends the cursor visibility state to the render widget.
IPC_MESSAGE_ROUTED1(InputMsg_CursorVisibilityChange,
@@ -136,10 +152,11 @@ IPC_MESSAGE_ROUTED2(InputMsg_ExtendSelectionAndDelete,
int /* after */)
// This message sends a string being composed with an input method.
-IPC_MESSAGE_ROUTED4(
+IPC_MESSAGE_ROUTED5(
InputMsg_ImeSetComposition,
base::string16, /* text */
std::vector<blink::WebCompositionUnderline>, /* underlines */
+ gfx::Range /* replacement_range */,
int, /* selectiont_start */
int /* selection_end */)
@@ -242,6 +259,8 @@ IPC_MESSAGE_ROUTED3(InputMsg_ActivateNearestFindResult,
// otherwise a race condition can happen.
IPC_MESSAGE_ROUTED0(InputMsg_ImeEventAck)
+// Request from browser to update text input state.
+IPC_MESSAGE_ROUTED0(InputMsg_RequestTextInputStateUpdate)
#endif
IPC_MESSAGE_ROUTED0(InputMsg_SyntheticGestureCompleted)
diff --git a/chromium/content/common/leveldb_wrapper.mojom b/chromium/content/common/leveldb_wrapper.mojom
new file mode 100644
index 00000000000..0035ebc5558
--- /dev/null
+++ b/chromium/content/common/leveldb_wrapper.mojom
@@ -0,0 +1,51 @@
+// Copyright 2016 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.
+
+module content.mojom;
+
+import "components/leveldb/public/interfaces/leveldb.mojom";
+
+// Gives information about changes to a LevelDB database.
+// Note that observer methods are called before the callbacks for the
+// LevelDBWrapper methods are run.
+interface LevelDBObserver {
+ KeyAdded(array<uint8> key, array<uint8> value, string source);
+ KeyChanged(array<uint8> key, array<uint8> new_value, array<uint8> old_value,
+ string source);
+ KeyDeleted(array<uint8> key, array<uint8> old_value, string source);
+ AllDeleted(string source);
+
+ // Since the GetAll call is synchronous, observers need this asynchronously
+ // delivered notification to avoid applying changes to the returned array
+ // that it already contains.
+ GetAllComplete(string source);
+};
+
+struct KeyValue {
+ array<uint8> key;
+ array<uint8> value;
+};
+
+// A wrapper around leveldb that supports giving notifications when values
+// change.
+interface LevelDBWrapper {
+ // Sets the database entry for |key| to |value|. Returns OK on success.
+ Put(array<uint8> key, array<uint8> value, string source) => (bool success);
+
+ // Remove the database entry (if any) for |key|. Returns OK on success, and a
+ // non-OK status on error. It is not an error if |key| did not exist in the
+ // database.
+ Delete(array<uint8> key, string source) => (bool success);
+
+ // Removes all the entries.
+ DeleteAll(string source) => (bool success);
+
+ // Returns the value of the |key|.
+ Get(array<uint8> key) => (bool success, array<uint8> value);
+
+ // Only used with small databases. Returns all key/value pairs.
+ [Sync]
+ GetAll(string source)
+ => (leveldb.DatabaseError status, array<KeyValue> data);
+};
diff --git a/chromium/content/common/mac/attributed_string_coder.h b/chromium/content/common/mac/attributed_string_coder.h
index 971088e856f..6976d4e0a4d 100644
--- a/chromium/content/common/mac/attributed_string_coder.h
+++ b/chromium/content/common/mac/attributed_string_coder.h
@@ -21,6 +21,11 @@ class NSAttributedString;
class NSDictionary;
#endif
+namespace base {
+class Pickle;
+class PickleIterator;
+}
+
namespace mac {
// This class will serialize the font information of an NSAttributedString so
@@ -100,16 +105,20 @@ namespace IPC {
template <>
struct ParamTraits<mac::AttributedStringCoder::EncodedString> {
typedef mac::AttributedStringCoder::EncodedString param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<mac::AttributedStringCoder::FontAttribute> {
typedef mac::AttributedStringCoder::FontAttribute param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
diff --git a/chromium/content/common/mac/attributed_string_coder.mm b/chromium/content/common/mac/attributed_string_coder.mm
index 85ceeb3655e..f8fa6b05271 100644
--- a/chromium/content/common/mac/attributed_string_coder.mm
+++ b/chromium/content/common/mac/attributed_string_coder.mm
@@ -122,13 +122,14 @@ namespace IPC {
using mac::AttributedStringCoder;
void ParamTraits<AttributedStringCoder::EncodedString>::Write(
- Message* m, const param_type& p) {
+ base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.string());
WriteParam(m, p.attributes());
}
bool ParamTraits<AttributedStringCoder::EncodedString>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
bool success = true;
@@ -147,13 +148,14 @@ void ParamTraits<AttributedStringCoder::EncodedString>::Log(
}
void ParamTraits<AttributedStringCoder::FontAttribute>::Write(
- Message* m, const param_type& p) {
+ base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.font_descriptor());
WriteParam(m, p.effective_range());
}
bool ParamTraits<AttributedStringCoder::FontAttribute>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
bool success = true;
diff --git a/chromium/content/common/media/OWNERS b/chromium/content/common/media/OWNERS
index 9d38af2734e..bd15b3e0625 100644
--- a/chromium/content/common/media/OWNERS
+++ b/chromium/content/common/media/OWNERS
@@ -1,9 +1,5 @@
-dalecurtis@chromium.org
-ddorwin@chromium.org
-jrummell@chromium.org
-sandersd@chromium.org
+file://media/OWNERS
tommi@chromium.org
-xhwang@chromium.org
# For security review of IPC message files.
per-file *_messages*.h=set noparent
diff --git a/chromium/content/common/media/audio_messages.h b/chromium/content/common/media/audio_messages.h
index 35e159c4f5e..7731dd6448a 100644
--- a/chromium/content/common/media/audio_messages.h
+++ b/chromium/content/common/media/audio_messages.h
@@ -17,6 +17,7 @@
#include "media/audio/audio_input_ipc.h"
#include "media/audio/audio_output_ipc.h"
#include "media/audio/audio_parameters.h"
+#include "media/gpu/ipc/common/media_param_traits.h"
#include "url/origin.h"
#undef IPC_MESSAGE_EXPORT
diff --git a/chromium/content/common/media/media_param_traits.cc b/chromium/content/common/media/media_param_traits.cc
index 5d5020c9654..07d630b2779 100644
--- a/chromium/content/common/media/media_param_traits.cc
+++ b/chromium/content/common/media/media_param_traits.cc
@@ -12,6 +12,7 @@
#include "media/audio/point.h"
#include "media/base/limits.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
using media::AudioParameters;
using media::ChannelLayout;
@@ -19,7 +20,7 @@ using media::VideoCaptureFormat;
namespace IPC {
-void ParamTraits<AudioParameters>::Write(Message* m,
+void ParamTraits<AudioParameters>::Write(base::Pickle* m,
const AudioParameters& p) {
WriteParam(m, p.format());
WriteParam(m, p.channel_layout());
@@ -31,7 +32,7 @@ void ParamTraits<AudioParameters>::Write(Message* m,
WriteParam(m, p.mic_positions());
}
-bool ParamTraits<AudioParameters>::Read(const Message* m,
+bool ParamTraits<AudioParameters>::Read(const base::Pickle* m,
base::PickleIterator* iter,
AudioParameters* r) {
AudioParameters::Format format;
@@ -63,7 +64,7 @@ void ParamTraits<AudioParameters>::Log(const AudioParameters& p,
l->append(base::StringPrintf("<AudioParameters>"));
}
-void ParamTraits<VideoCaptureFormat>::Write(Message* m,
+void ParamTraits<VideoCaptureFormat>::Write(base::Pickle* m,
const VideoCaptureFormat& p) {
WriteParam(m, p.frame_size);
WriteParam(m, p.frame_rate);
@@ -71,7 +72,7 @@ void ParamTraits<VideoCaptureFormat>::Write(Message* m,
WriteParam(m, p.pixel_storage);
}
-bool ParamTraits<VideoCaptureFormat>::Read(const Message* m,
+bool ParamTraits<VideoCaptureFormat>::Read(const base::Pickle* m,
base::PickleIterator* iter,
VideoCaptureFormat* r) {
if (!ReadParam(m, iter, &r->frame_size) ||
diff --git a/chromium/content/common/media/media_param_traits.h b/chromium/content/common/media/media_param_traits.h
index f035b402c69..70675edba3e 100644
--- a/chromium/content/common/media/media_param_traits.h
+++ b/chromium/content/common/media/media_param_traits.h
@@ -19,16 +19,20 @@ namespace IPC {
template <>
struct CONTENT_EXPORT ParamTraits<media::AudioParameters> {
typedef media::AudioParameters param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<media::VideoCaptureFormat> {
typedef media::VideoCaptureFormat param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
diff --git a/chromium/content/common/media/media_player_delegate_messages.h b/chromium/content/common/media/media_player_delegate_messages.h
new file mode 100644
index 00000000000..98d5d47ee94
--- /dev/null
+++ b/chromium/content/common/media/media_player_delegate_messages.h
@@ -0,0 +1,51 @@
+// Copyright 2016 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.
+
+// IPC messages for interactions between the WebMediaPlayerDelegate in the
+// renderer process and MediaWebContentsObserver in the browser process.
+// Multiply-included message file, hence no include guard.
+
+#include <stdint.h>
+
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+#include "ipc/ipc_message_macros.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START MediaPlayerDelegateMsgStart
+
+// ----------------------------------------------------------------------------
+// Messages from the browser to the renderer requesting playback state changes.
+// ----------------------------------------------------------------------------
+
+IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Pause,
+ int /* delegate_id, distinguishes instances */)
+
+IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Play,
+ int /* delegate_id, distinguishes instances */)
+
+IPC_MESSAGE_ROUTED0(MediaPlayerDelegateMsg_SuspendAllMediaPlayers)
+
+IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_UpdateVolumeMultiplier,
+ int /* delegate_id, distinguishes instances */,
+ double /* multiplier */)
+
+// ----------------------------------------------------------------------------
+// Messages from the renderer notifying the browser of playback state changes.
+// ----------------------------------------------------------------------------
+
+IPC_MESSAGE_ROUTED1(MediaPlayerDelegateHostMsg_OnMediaDestroyed,
+ int /* delegate_id, distinguishes instances */)
+
+IPC_MESSAGE_ROUTED2(MediaPlayerDelegateHostMsg_OnMediaPaused,
+ int /* delegate_id, distinguishes instances */,
+ bool /* reached end of stream */)
+
+IPC_MESSAGE_ROUTED5(MediaPlayerDelegateHostMsg_OnMediaPlaying,
+ int /* delegate_id, distinguishes instances */,
+ bool /* has_video */,
+ bool /* has_audio */,
+ bool /* is_remote */,
+ base::TimeDelta /* duration */)
diff --git a/chromium/content/common/media/media_player_messages_android.h b/chromium/content/common/media/media_player_messages_android.h
index b4e0ba6ebd4..0aab6d85a5d 100644
--- a/chromium/content/common/media/media_player_messages_android.h
+++ b/chromium/content/common/media/media_player_messages_android.h
@@ -9,7 +9,9 @@
#include "content/common/content_export.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/android/demuxer_stream_player_params.h"
+#include "media/base/decrypt_config.h"
#include "media/blink/renderer_media_player_interface.h"
+#include "media/gpu/ipc/common/media_param_traits.h"
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
@@ -68,6 +70,8 @@ IPC_STRUCT_BEGIN(MediaPlayerHostMsg_Initialize_Params)
IPC_STRUCT_MEMBER(GURL, first_party_for_cookies)
IPC_STRUCT_MEMBER(GURL, frame_url)
IPC_STRUCT_MEMBER(bool, allow_credentials)
+ IPC_STRUCT_MEMBER(int, delegate_id)
+ IPC_STRUCT_MEMBER(int, media_session_id)
IPC_STRUCT_END()
// Chrome for Android seek message sequence is:
@@ -193,6 +197,10 @@ IPC_MESSAGE_ROUTED2(MediaPlayerMsg_ConnectedToRemoteDevice,
IPC_MESSAGE_ROUTED1(MediaPlayerMsg_DisconnectedFromRemoteDevice,
int /* player_id */)
+// The remote playback device selection has been cancelled.
+IPC_MESSAGE_ROUTED1(MediaPlayerMsg_CancelledRemotePlaybackRequest,
+ int /* player_id */)
+
// The availability of remote devices has changed
IPC_MESSAGE_ROUTED2(MediaPlayerMsg_RemoteRouteAvailabilityChanged,
int /* player_id */,
diff --git a/chromium/content/common/media/media_session_messages_android.h b/chromium/content/common/media/media_session_messages_android.h
index 18a63844d70..266ee273bcf 100644
--- a/chromium/content/common/media/media_session_messages_android.h
+++ b/chromium/content/common/media/media_session_messages_android.h
@@ -7,12 +7,19 @@
#include "content/common/android/gin_java_bridge_errors.h"
#include "content/common/content_export.h"
+#include "content/public/common/media_metadata.h"
#include "ipc/ipc_message_macros.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START MediaSessionMsgStart
+IPC_STRUCT_TRAITS_BEGIN(content::MediaMetadata)
+ IPC_STRUCT_TRAITS_MEMBER(title)
+ IPC_STRUCT_TRAITS_MEMBER(artist)
+ IPC_STRUCT_TRAITS_MEMBER(album)
+IPC_STRUCT_TRAITS_END()
+
// Messages for notifying the render process of media session status -------
IPC_MESSAGE_ROUTED2(MediaSessionMsg_DidActivate,
@@ -30,3 +37,7 @@ IPC_MESSAGE_ROUTED2(MediaSessionHostMsg_Activate,
IPC_MESSAGE_ROUTED2(MediaSessionHostMsg_Deactivate,
int /* session_id */,
int /* request_id */)
+
+IPC_MESSAGE_ROUTED2(MediaSessionHostMsg_SetMetadata,
+ int /* request_id*/,
+ content::MediaMetadata /* metadata */)
diff --git a/chromium/content/common/media/media_stream_options.cc b/chromium/content/common/media/media_stream_options.cc
index c942f460986..1b2b1e2750a 100644
--- a/chromium/content/common/media/media_stream_options.cc
+++ b/chromium/content/common/media/media_stream_options.cc
@@ -27,6 +27,8 @@ TrackControls::TrackControls()
TrackControls::TrackControls(bool request)
: requested(request) {}
+TrackControls::TrackControls(const TrackControls& other) = default;
+
TrackControls::~TrackControls() {}
StreamControls::StreamControls()
diff --git a/chromium/content/common/media/media_stream_options.h b/chromium/content/common/media/media_stream_options.h
index 4d61d579221..b815c602cdf 100644
--- a/chromium/content/common/media/media_stream_options.h
+++ b/chromium/content/common/media/media_stream_options.h
@@ -36,6 +36,7 @@ struct CONTENT_EXPORT TrackControls {
public:
TrackControls();
TrackControls(bool request);
+ TrackControls(const TrackControls& other);
~TrackControls();
bool requested;
diff --git a/chromium/content/common/media/surface_view_manager_messages_android.h b/chromium/content/common/media/surface_view_manager_messages_android.h
new file mode 100644
index 00000000000..72426c2539d
--- /dev/null
+++ b/chromium/content/common/media/surface_view_manager_messages_android.h
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+// IPC messages for surface view manager.
+// Multiply-included message file, hence no include guard.
+
+#include "content/common/content_export.h"
+#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/geometry/size.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START SurfaceViewManagerMsgStart
+
+// Message sent from the renderer to the browser
+
+IPC_MESSAGE_ROUTED1(SurfaceViewManagerHostMsg_CreateFullscreenSurface,
+ gfx::Size /* video_natural_size */)
+IPC_MESSAGE_ROUTED1(SurfaceViewManagerHostMsg_NaturalSizeChanged,
+ gfx::Size /* size */)
+
+// Message sent from the browser to the renderer
+
+IPC_MESSAGE_ROUTED1(SurfaceViewManagerMsg_FullscreenSurfaceCreated,
+ int /* surface_id */)
diff --git a/chromium/content/common/media/video_capture_messages.h b/chromium/content/common/media/video_capture_messages.h
index be1a179bda6..5241898beb2 100644
--- a/chromium/content/common/media/video_capture_messages.h
+++ b/chromium/content/common/media/video_capture_messages.h
@@ -19,7 +19,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(content::VideoCaptureState,
content::VIDEO_CAPTURE_STATE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(media::ResolutionChangePolicy,
media::RESOLUTION_POLICY_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelFormat, media::PIXEL_FORMAT_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(media::VideoFrame::StorageType,
media::VideoFrame::STORAGE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelStorage, media::PIXEL_STORAGE_MAX)
@@ -108,6 +107,11 @@ IPC_MESSAGE_CONTROL3(VideoCaptureHostMsg_Resume,
media::VideoCaptureSessionId, /* session_id */
media::VideoCaptureParams /* params */)
+// Requests that the video capturer send a frame "soon" (e.g., to resolve
+// picture loss or quality issues).
+IPC_MESSAGE_CONTROL1(VideoCaptureHostMsg_RequestRefreshFrame,
+ int /* device_id */)
+
// Close the video capture specified by |device_id|.
IPC_MESSAGE_CONTROL1(VideoCaptureHostMsg_Stop,
int /* device_id */)
diff --git a/chromium/content/common/memory_benchmark_messages.h b/chromium/content/common/memory_benchmark_messages.h
deleted file mode 100644
index 3955630496a..00000000000
--- a/chromium/content/common/memory_benchmark_messages.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2013 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.
-
-// IPC messages for memory benchmark.
-// Multiply-included message file, hence no include guard.
-
-#include <string>
-
-#include "ipc/ipc_message_macros.h"
-
-#define IPC_MESSAGE_START MemoryBenchmarkMsgStart
-
-IPC_MESSAGE_CONTROL1(MemoryBenchmarkHostMsg_HeapProfilerDump,
- std::string /* dump reason */)
diff --git a/chromium/content/common/message_router.cc b/chromium/content/common/message_router.cc
deleted file mode 100644
index ac6361e4fe6..00000000000
--- a/chromium/content/common/message_router.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2011 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 "content/common/message_router.h"
-
-#include "ipc/ipc_message.h"
-
-namespace content {
-
-MessageRouter::MessageRouter() {
-}
-
-MessageRouter::~MessageRouter() {
-}
-
-bool MessageRouter::OnControlMessageReceived(const IPC::Message& msg) {
- NOTREACHED() <<
- "should override in subclass if you care about control messages";
- return false;
-}
-
-bool MessageRouter::Send(IPC::Message* msg) {
- NOTREACHED() <<
- "should override in subclass if you care about sending messages";
- return false;
-}
-
-bool MessageRouter::AddRoute(int32_t routing_id, IPC::Listener* listener) {
- if (routes_.Lookup(routing_id)) {
- DLOG(ERROR) << "duplicate routing ID";
- return false;
- }
- routes_.AddWithID(listener, routing_id);
- return true;
-}
-
-void MessageRouter::RemoveRoute(int32_t routing_id) {
- routes_.Remove(routing_id);
-}
-
-bool MessageRouter::OnMessageReceived(const IPC::Message& msg) {
- if (msg.routing_id() == MSG_ROUTING_CONTROL)
- return OnControlMessageReceived(msg);
-
- return RouteMessage(msg);
-}
-
-bool MessageRouter::RouteMessage(const IPC::Message& msg) {
- IPC::Listener* listener = routes_.Lookup(msg.routing_id());
- if (!listener)
- return false;
-
- return listener->OnMessageReceived(msg);
-}
-
-} // namespace content
diff --git a/chromium/content/common/message_router.h b/chromium/content/common/message_router.h
deleted file mode 100644
index fea73252b35..00000000000
--- a/chromium/content/common/message_router.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 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 CONTENT_COMMON_MESSAGE_ROUTER_H_
-#define CONTENT_COMMON_MESSAGE_ROUTER_H_
-
-#include <stdint.h>
-
-#include "base/id_map.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_sender.h"
-
-// The MessageRouter handles all incoming messages sent to it by routing them
-// to the correct listener. Routing is based on the Message's routing ID.
-// Since routing IDs are typically assigned asynchronously by the browser
-// process, the MessageRouter has the notion of pending IDs for listeners that
-// have not yet been assigned a routing ID.
-//
-// When a message arrives, the routing ID is used to index the set of routes to
-// find a listener. If a listener is found, then the message is passed to it.
-// Otherwise, the message is ignored if its routing ID is not equal to
-// MSG_ROUTING_CONTROL.
-//
-// The MessageRouter supports the IPC::Sender interface for outgoing messages,
-// but does not define a meaningful implementation of it. The subclass of
-// MessageRouter is intended to provide that if appropriate.
-//
-// The MessageRouter can be used as a concrete class provided its Send method
-// is not called and it does not receive any control messages.
-
-namespace content {
-
-class CONTENT_EXPORT MessageRouter : public IPC::Listener, public IPC::Sender {
- public:
- MessageRouter();
- ~MessageRouter() override;
-
- // Implemented by subclasses to handle control messages
- virtual bool OnControlMessageReceived(const IPC::Message& msg);
-
- // IPC::Listener implementation:
- bool OnMessageReceived(const IPC::Message& msg) override;
-
- // Like OnMessageReceived, except it only handles routed messages. Returns
- // true if the message was dispatched, or false if there was no listener for
- // that route id.
- virtual bool RouteMessage(const IPC::Message& msg);
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* msg) override;
-
- // Called to add a listener for a particular message routing ID.
- // Returns true if succeeded.
- bool AddRoute(int32_t routing_id, IPC::Listener* listener);
-
- // Called to remove a listener for a particular message routing ID.
- void RemoveRoute(int32_t routing_id);
-
- private:
- // A list of all listeners with assigned routing IDs.
- IDMap<IPC::Listener> routes_;
-
- DISALLOW_COPY_AND_ASSIGN(MessageRouter);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_MESSAGE_ROUTER_H_
diff --git a/chromium/content/common/mojo/DEPS b/chromium/content/common/mojo/DEPS
index c70d064e525..0f2f39efd65 100644
--- a/chromium/content/common/mojo/DEPS
+++ b/chromium/content/common/mojo/DEPS
@@ -1,6 +1,5 @@
include_rules = [
- "+mojo/shell/public/cpp",
- "+mojo/shell/public/interfaces",
"+mojo/converters/network",
- "+mojo/runner/child",
+ "+mojo/edk/embedder",
+ "+mojo/shell",
]
diff --git a/chromium/content/common/mojo/channel_init.cc b/chromium/content/common/mojo/channel_init.cc
index 967fb10be60..c8172ab2cd3 100644
--- a/chromium/content/common/mojo/channel_init.cc
+++ b/chromium/content/common/mojo/channel_init.cc
@@ -8,55 +8,25 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
+#include "base/task_runner.h"
#include "base/thread_task_runner_handle.h"
-#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/embedder.h"
namespace content {
-ChannelInit::ChannelInit() : channel_info_(nullptr), weak_factory_(this) {}
+ChannelInit::ChannelInit() {}
-ChannelInit::~ChannelInit() {
- if (channel_info_)
- mojo::embedder::DestroyChannel(channel_info_,
- base::Bind(&base::DoNothing), nullptr);
-}
+ChannelInit::~ChannelInit() {}
mojo::ScopedMessagePipeHandle ChannelInit::Init(
base::PlatformFile file,
scoped_refptr<base::TaskRunner> io_thread_task_runner) {
- scoped_ptr<IPC::ScopedIPCSupport> ipc_support(
- new IPC::ScopedIPCSupport(io_thread_task_runner));
- mojo::ScopedMessagePipeHandle message_pipe = mojo::embedder::CreateChannel(
- mojo::embedder::ScopedPlatformHandle(
- mojo::embedder::PlatformHandle(file)),
- base::Bind(&ChannelInit::OnCreatedChannel, weak_factory_.GetWeakPtr(),
- base::Passed(&ipc_support)),
- base::ThreadTaskRunnerHandle::Get());
- return message_pipe;
-}
-
-void ChannelInit::WillDestroySoon() {
- if (channel_info_)
- mojo::embedder::WillDestroyChannelSoon(channel_info_);
-}
-
-// static
-void ChannelInit::OnCreatedChannel(
- base::WeakPtr<ChannelInit> self,
- scoped_ptr<IPC::ScopedIPCSupport> ipc_support,
- mojo::embedder::ChannelInfo* channel) {
- // If |self| was already destroyed, shut the channel down.
- if (!self) {
- mojo::embedder::DestroyChannel(channel,
- base::Bind(&base::DoNothing), nullptr);
- return;
- }
-
- DCHECK(!self->channel_info_);
- self->channel_info_ = channel;
- self->ipc_support_ = std::move(ipc_support);
+ return mojo::edk::CreateMessagePipe(
+ mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(file)));
}
} // namespace content
diff --git a/chromium/content/common/mojo/channel_init.h b/chromium/content/common/mojo/channel_init.h
index acdc5752c95..6b9daae2dd0 100644
--- a/chromium/content/common/mojo/channel_init.h
+++ b/chromium/content/common/mojo/channel_init.h
@@ -8,11 +8,8 @@
#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
-#include "ipc/mojo/scoped_ipc_support.h"
#include "mojo/public/cpp/system/message_pipe.h"
-#include "third_party/mojo/src/mojo/edk/embedder/channel_info_forward.h"
namespace base {
class TaskRunner;
@@ -22,35 +19,20 @@ namespace content {
// ChannelInit handles creation and destruction of the Mojo channel. It is not
// thread-safe, but may be used on any single thread with a MessageLoop.
+//
+// TODO(rockot): Get rid of this class ASAP (i.e. once the patch which includes
+// this TODO has stuck for a bit) since it's no longer necessary.
class CONTENT_EXPORT ChannelInit {
public:
ChannelInit();
~ChannelInit();
- // Initializes the channel. This takes ownership of |file|. Returns the
- // primordial MessagePipe for the channel.
+ // Initializes the channel. This takes ownership of |file|.
mojo::ScopedMessagePipeHandle Init(
base::PlatformFile file,
scoped_refptr<base::TaskRunner> io_thread_task_runner);
- // Notifies the channel that we (hence it) will soon be destroyed.
- void WillDestroySoon();
-
private:
- // Invoked on the thread on which this object lives once the channel has been
- // established. This is a static method that takes a weak pointer to self,
- // since we want to destroy the channel if we were destroyed first.
- static void OnCreatedChannel(
- base::WeakPtr<ChannelInit> self,
- scoped_ptr<IPC::ScopedIPCSupport> ipc_support,
- mojo::embedder::ChannelInfo* channel);
-
- // If non-null the channel has been established.
- mojo::embedder::ChannelInfo* channel_info_;
-
- scoped_ptr<IPC::ScopedIPCSupport> ipc_support_;
- base::WeakPtrFactory<ChannelInit> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(ChannelInit);
};
diff --git a/chromium/content/common/mojo/current_thread_loader.cc b/chromium/content/common/mojo/current_thread_loader.cc
new file mode 100644
index 00000000000..eb64b150863
--- /dev/null
+++ b/chromium/content/common/mojo/current_thread_loader.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 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 "content/common/mojo/current_thread_loader.h"
+
+namespace content {
+
+CurrentThreadLoader::CurrentThreadLoader(const ApplicationFactory& factory)
+ : factory_(factory) {}
+
+CurrentThreadLoader::~CurrentThreadLoader() {}
+
+void CurrentThreadLoader::Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) {
+ if (!shell_client_) {
+ shell_client_ = factory_.Run();
+ factory_ = ApplicationFactory();
+ }
+
+ connections_.push_back(make_scoped_ptr(
+ new mojo::ShellConnection(shell_client_.get(), std::move(request))));
+}
+
+} // namespace content
diff --git a/chromium/content/common/mojo/current_thread_loader.h b/chromium/content/common/mojo/current_thread_loader.h
new file mode 100644
index 00000000000..e5e6e35de2c
--- /dev/null
+++ b/chromium/content/common/mojo/current_thread_loader.h
@@ -0,0 +1,46 @@
+// Copyright 2016 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 CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
+#define CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "mojo/shell/loader.h"
+#include "mojo/shell/public/cpp/shell_client.h"
+#include "mojo/shell/public/cpp/shell_connection.h"
+
+namespace content {
+
+// A Loader which loads a single type of app from a mojo::ShellClientFactory on
+// the current thread.
+class CurrentThreadLoader : public mojo::shell::Loader {
+ public:
+ using ApplicationFactory = base::Callback<scoped_ptr<mojo::ShellClient>()>;
+
+ explicit CurrentThreadLoader(const ApplicationFactory& factory);
+ ~CurrentThreadLoader() override;
+
+ // mojo::shell::Loader:
+ void Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) override;
+
+ private:
+ // The factory used to create new instances of the application delegate. This
+ // is called exactly once since all connections share a single client.
+ ApplicationFactory factory_;
+
+ // Our shared shell client, passed to each connection.
+ scoped_ptr<mojo::ShellClient> shell_client_;
+
+ std::vector<scoped_ptr<mojo::ShellConnection>> connections_;
+
+ DISALLOW_COPY_AND_ASSIGN(CurrentThreadLoader);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_MOJO_CURRENT_THREAD_LOADER_H_
diff --git a/chromium/content/common/mojo/mojo_messages.h b/chromium/content/common/mojo/mojo_messages.h
index 4ed553641ee..1232902be37 100644
--- a/chromium/content/common/mojo/mojo_messages.h
+++ b/chromium/content/common/mojo/mojo_messages.h
@@ -20,8 +20,3 @@
// Mojo IPC is bootstrapped over Chrome IPC via this message.
IPC_MESSAGE_CONTROL1(MojoMsg_Activate,
IPC::PlatformFileForTransit /* handle */)
-
-// Mojo IPC to an external shell is bootstrapped over Chrome IPC via this
-// message.
-IPC_MESSAGE_CONTROL1(MojoMsg_BindExternalMojoShellHandle,
- IPC::PlatformFileForTransit /* handle */)
diff --git a/chromium/content/common/mojo/mojo_shell_connection_impl.cc b/chromium/content/common/mojo/mojo_shell_connection_impl.cc
index 34bf88a4766..5214096007a 100644
--- a/chromium/content/common/mojo/mojo_shell_connection_impl.cc
+++ b/chromium/content/common/mojo/mojo_shell_connection_impl.cc
@@ -8,15 +8,19 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/threading/thread_local.h"
-#include "mojo/converters/network/network_type_converters.h"
-#include "mojo/runner/child/runner_connection.h"
-#include "mojo/shell/public/cpp/application_delegate.h"
-#include "mojo/shell/public/cpp/application_impl.h"
+#include "content/public/common/content_switches.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/shell/public/cpp/shell_client.h"
+#include "mojo/shell/public/cpp/shell_connection.h"
+#include "mojo/shell/runner/common/client_util.h"
namespace content {
namespace {
+
using MojoShellConnectionPtr =
base::ThreadLocalPointer<MojoShellConnectionImpl>;
@@ -24,69 +28,115 @@ using MojoShellConnectionPtr =
base::LazyInstance<MojoShellConnectionPtr>::Leaky lazy_tls_ptr =
LAZY_INSTANCE_INITIALIZER;
+MojoShellConnection::Factory* mojo_shell_connection_factory = nullptr;
+
} // namespace
bool IsRunningInMojoShell() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- "mojo-platform-channel-handle");
+ return mojo_shell_connection_factory ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch);
+}
+
+bool ShouldWaitForShell() {
+ return mojo_shell_connection_factory ||
+ (IsRunningInMojoShell() &&
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kWaitForMojoShell));
+}
+
+// static
+bool MojoShellConnectionImpl::CreateUsingFactory() {
+ if (mojo_shell_connection_factory) {
+ DCHECK(!lazy_tls_ptr.Pointer()->Get());
+ mojo_shell_connection_factory->Run();
+ DCHECK(lazy_tls_ptr.Pointer()->Get());
+ return true;
+ }
+ return false;
}
// static
void MojoShellConnectionImpl::Create() {
DCHECK(!lazy_tls_ptr.Pointer()->Get());
- MojoShellConnectionImpl* connection = new MojoShellConnectionImpl;
+ MojoShellConnectionImpl* connection =
+ new MojoShellConnectionImpl(true /* external */);
lazy_tls_ptr.Pointer()->Set(connection);
}
// static
+void MojoShellConnection::Create(mojo::shell::mojom::ShellClientRequest request,
+ bool is_external) {
+ DCHECK(!lazy_tls_ptr.Pointer()->Get());
+ MojoShellConnectionImpl* connection =
+ new MojoShellConnectionImpl(is_external);
+ lazy_tls_ptr.Pointer()->Set(connection);
+ connection->shell_connection_.reset(
+ new mojo::ShellConnection(connection, std::move(request)));
+ if (is_external)
+ connection->WaitForShellIfNecessary();
+}
+
+// static
+void MojoShellConnection::SetFactoryForTest(Factory* factory) {
+ DCHECK(!lazy_tls_ptr.Pointer()->Get());
+ mojo_shell_connection_factory = factory;
+}
+
+// static
MojoShellConnectionImpl* MojoShellConnectionImpl::Get() {
+ // Assume that if a mojo_shell_connection_factory was set that it did not
+ // create a MojoShellConnectionImpl.
return static_cast<MojoShellConnectionImpl*>(MojoShellConnection::Get());
}
-void MojoShellConnectionImpl::BindToCommandLinePlatformChannel() {
- DCHECK(IsRunningInMojoShell());
- if (initialized_)
- return;
- WaitForShell(mojo::ScopedMessagePipeHandle());
+void MojoShellConnectionImpl::BindToRequestFromCommandLine() {
+ DCHECK(!shell_connection_);
+ shell_connection_.reset(new mojo::ShellConnection(
+ this, mojo::shell::GetShellClientRequestFromCommandLine()));
+ WaitForShellIfNecessary();
}
-void MojoShellConnectionImpl::BindToMessagePipe(
- mojo::ScopedMessagePipeHandle handle) {
- if (initialized_)
- return;
- WaitForShell(std::move(handle));
-}
+MojoShellConnectionImpl::MojoShellConnectionImpl(bool external)
+ : external_(external) {}
-MojoShellConnectionImpl::MojoShellConnectionImpl() : initialized_(false) {}
MojoShellConnectionImpl::~MojoShellConnectionImpl() {
STLDeleteElements(&listeners_);
}
-void MojoShellConnectionImpl::WaitForShell(
- mojo::ScopedMessagePipeHandle handle) {
- mojo::InterfaceRequest<mojo::Application> application_request;
- runner_connection_.reset(mojo::runner::RunnerConnection::ConnectToRunner(
- &application_request, std::move(handle)));
- application_impl_.reset(
- new mojo::ApplicationImpl(this, std::move(application_request)));
- application_impl_->WaitForInitialize();
+void MojoShellConnectionImpl::WaitForShellIfNecessary() {
+ // TODO(rockot): Remove this. http://crbug.com/594852.
+ if (ShouldWaitForShell()) {
+ base::RunLoop wait_loop;
+ shell_connection_->set_initialize_handler(wait_loop.QuitClosure());
+ wait_loop.Run();
+ }
}
-void MojoShellConnectionImpl::Initialize(mojo::ApplicationImpl* application) {
- initialized_ = true;
+void MojoShellConnectionImpl::Initialize(mojo::Connector* connector,
+ const mojo::Identity& identity,
+ uint32_t id) {
}
-bool MojoShellConnectionImpl::ConfigureIncomingConnection(
- mojo::ApplicationConnection* connection) {
+bool MojoShellConnectionImpl::AcceptConnection(mojo::Connection* connection) {
bool found = false;
for (auto listener : listeners_)
- found |= listener->ConfigureIncomingConnection(connection);
+ found |= listener->AcceptConnection(connection);
return found;
}
-mojo::ApplicationImpl* MojoShellConnectionImpl::GetApplication() {
- DCHECK(initialized_);
- return application_impl_.get();
+mojo::Connector* MojoShellConnectionImpl::GetConnector() {
+ DCHECK(shell_connection_);
+ return shell_connection_->connector();
+}
+
+bool MojoShellConnectionImpl::UsingExternalShell() const {
+ return external_;
+}
+
+void MojoShellConnectionImpl::SetConnectionLostClosure(
+ const base::Closure& closure) {
+ shell_connection_->set_connection_lost_closure(closure);
}
void MojoShellConnectionImpl::AddListener(Listener* listener) {
diff --git a/chromium/content/common/mojo/mojo_shell_connection_impl.h b/chromium/content/common/mojo/mojo_shell_connection_impl.h
index 3f7ecfa05fc..3f1a188eb55 100644
--- a/chromium/content/common/mojo/mojo_shell_connection_impl.h
+++ b/chromium/content/common/mojo/mojo_shell_connection_impl.h
@@ -11,13 +11,9 @@
#include "base/memory/scoped_ptr.h"
#include "content/public/common/mojo_shell_connection.h"
#include "mojo/public/cpp/system/message_pipe.h"
-#include "mojo/shell/public/cpp/application_delegate.h"
-
-namespace mojo {
-namespace runner {
-class RunnerConnection;
-}
-}
+#include "mojo/shell/public/cpp/shell.h"
+#include "mojo/shell/public/cpp/shell_client.h"
+#include "mojo/shell/public/cpp/shell_connection.h"
namespace content {
@@ -25,8 +21,12 @@ namespace content {
bool IsRunningInMojoShell();
class MojoShellConnectionImpl : public MojoShellConnection,
- public mojo::ApplicationDelegate {
+ public mojo::ShellClient {
public:
+ // Creates the MojoShellConnection using MojoShellConnection::Factory. Returns
+ // true if a factory was set and the connection was created, false otherwise.
+ static bool CreateUsingFactory();
+
// Creates an instance of this class and stuffs it in TLS on the calling
// thread. Retrieve it using MojoShellConnection::Get().
static void Create();
@@ -36,37 +36,33 @@ class MojoShellConnectionImpl : public MojoShellConnection,
// Mojo shell).
static MojoShellConnectionImpl* Get();
- // Blocks the calling thread until calling GetApplication() will return an
- // Initialized() application with a bound ShellPtr. This call is a no-op
- // if the connection has already been initialized.
- void BindToCommandLinePlatformChannel();
-
- // Same as BindToCommandLinePlatformChannel(), but receives a |handle| instead
- // of looking for one on the command line.
- void BindToMessagePipe(mojo::ScopedMessagePipeHandle handle);
+ // Binds the shell connection to a ShellClientFactory request pipe from the
+ // command line. This must only be called once.
+ void BindToRequestFromCommandLine();
private:
- MojoShellConnectionImpl();
+ friend class MojoShellConnection;
+
+ explicit MojoShellConnectionImpl(bool external);
~MojoShellConnectionImpl() override;
- // mojo::ApplicationDelegate:
- void Initialize(mojo::ApplicationImpl* application) override;
- bool ConfigureIncomingConnection(
- mojo::ApplicationConnection* connection) override;
+ void WaitForShellIfNecessary();
+
+ // mojo::ShellClient:
+ void Initialize(mojo::Connector* connector,
+ const mojo::Identity& identity,
+ uint32_t id) override;
+ bool AcceptConnection(mojo::Connection* connection) override;
// MojoShellConnection:
- mojo::ApplicationImpl* GetApplication() override;
+ mojo::Connector* GetConnector() override;
+ bool UsingExternalShell() const override;
+ void SetConnectionLostClosure(const base::Closure& closure) override;
void AddListener(Listener* listener) override;
void RemoveListener(Listener* listener) override;
- // Blocks the calling thread until a connection to the spawning shell is
- // established, an Application request from it is bound, and the Initialize()
- // method on that application is called.
- void WaitForShell(mojo::ScopedMessagePipeHandle handle);
-
- bool initialized_;
- scoped_ptr<mojo::runner::RunnerConnection> runner_connection_;
- scoped_ptr<mojo::ApplicationImpl> application_impl_;
+ const bool external_;
+ scoped_ptr<mojo::ShellConnection> shell_connection_;
std::vector<Listener*> listeners_;
DISALLOW_COPY_AND_ASSIGN(MojoShellConnectionImpl);
diff --git a/chromium/content/common/mojo/service_registry_impl.cc b/chromium/content/common/mojo/service_registry_impl.cc
index a55864f92ea..b26c60990be 100644
--- a/chromium/content/common/mojo/service_registry_impl.cc
+++ b/chromium/content/common/mojo/service_registry_impl.cc
@@ -21,27 +21,26 @@ ServiceRegistryImpl::~ServiceRegistryImpl() {
}
void ServiceRegistryImpl::Bind(
- mojo::InterfaceRequest<mojo::ServiceProvider> request) {
+ mojo::shell::mojom::InterfaceProviderRequest request) {
binding_.Bind(std::move(request));
binding_.set_connection_error_handler(base::Bind(
&ServiceRegistryImpl::OnConnectionError, base::Unretained(this)));
}
void ServiceRegistryImpl::BindRemoteServiceProvider(
- mojo::ServiceProviderPtr service_provider) {
+ mojo::shell::mojom::InterfaceProviderPtr service_provider) {
CHECK(!remote_provider_);
remote_provider_ = std::move(service_provider);
while (!pending_connects_.empty()) {
- remote_provider_->ConnectToService(
+ remote_provider_->GetInterface(
mojo::String::From(pending_connects_.front().first),
mojo::ScopedMessagePipeHandle(pending_connects_.front().second));
pending_connects_.pop();
}
}
-void ServiceRegistryImpl::AddService(
- const std::string& service_name,
- const base::Callback<void(mojo::ScopedMessagePipeHandle)> service_factory) {
+void ServiceRegistryImpl::AddService(const std::string& service_name,
+ const ServiceFactory service_factory) {
service_factories_[service_name] = service_factory;
}
@@ -52,15 +51,31 @@ void ServiceRegistryImpl::RemoveService(const std::string& service_name) {
void ServiceRegistryImpl::ConnectToRemoteService(
const base::StringPiece& service_name,
mojo::ScopedMessagePipeHandle handle) {
+ auto override_it = service_overrides_.find(service_name.as_string());
+ if (override_it != service_overrides_.end()) {
+ override_it->second.Run(std::move(handle));
+ return;
+ }
+
if (!remote_provider_) {
pending_connects_.push(
std::make_pair(service_name.as_string(), handle.release()));
return;
}
- remote_provider_->ConnectToService(
+ remote_provider_->GetInterface(
mojo::String::From(service_name.as_string()), std::move(handle));
}
+void ServiceRegistryImpl::AddServiceOverrideForTesting(
+ const std::string& service_name,
+ const ServiceFactory& factory) {
+ service_overrides_[service_name] = factory;
+}
+
+void ServiceRegistryImpl::ClearServiceOverridesForTesting() {
+ service_overrides_.clear();
+}
+
bool ServiceRegistryImpl::IsBound() const {
return binding_.is_bound();
}
@@ -69,12 +84,10 @@ base::WeakPtr<ServiceRegistry> ServiceRegistryImpl::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-void ServiceRegistryImpl::ConnectToService(
+void ServiceRegistryImpl::GetInterface(
const mojo::String& name,
mojo::ScopedMessagePipeHandle client_handle) {
- std::map<std::string,
- base::Callback<void(mojo::ScopedMessagePipeHandle)> >::iterator it =
- service_factories_.find(name);
+ auto it = service_factories_.find(name);
if (it == service_factories_.end())
return;
diff --git a/chromium/content/common/mojo/service_registry_impl.h b/chromium/content/common/mojo/service_registry_impl.h
index 5e4fd73fd91..807924cb1e3 100644
--- a/chromium/content/common/mojo/service_registry_impl.h
+++ b/chromium/content/common/mojo/service_registry_impl.h
@@ -16,53 +16,60 @@
#include "content/public/common/service_registry.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/core.h"
-#include "mojo/shell/public/interfaces/service_provider.mojom.h"
+#include "mojo/shell/public/interfaces/interface_provider.mojom.h"
namespace content {
class CONTENT_EXPORT ServiceRegistryImpl
: public ServiceRegistry,
- public NON_EXPORTED_BASE(mojo::ServiceProvider) {
+ public NON_EXPORTED_BASE(mojo::shell::mojom::InterfaceProvider) {
public:
+ using ServiceFactory = base::Callback<void(mojo::ScopedMessagePipeHandle)>;
+
ServiceRegistryImpl();
~ServiceRegistryImpl() override;
// Binds this ServiceProvider implementation to a message pipe endpoint.
- void Bind(mojo::InterfaceRequest<mojo::ServiceProvider> request);
+ void Bind(mojo::shell::mojom::InterfaceProviderRequest request);
// Binds to a remote ServiceProvider. This will expose added services to the
// remote ServiceProvider with the corresponding handle and enable
// ConnectToRemoteService to provide access to services exposed by the remote
// ServiceProvider.
- void BindRemoteServiceProvider(mojo::ServiceProviderPtr service_provider);
+ void BindRemoteServiceProvider(
+ mojo::shell::mojom::InterfaceProviderPtr service_provider);
// ServiceRegistry overrides.
void AddService(const std::string& service_name,
- const base::Callback<void(mojo::ScopedMessagePipeHandle)>
- service_factory) override;
+ const ServiceFactory service_factory) override;
void RemoveService(const std::string& service_name) override;
void ConnectToRemoteService(const base::StringPiece& service_name,
mojo::ScopedMessagePipeHandle handle) override;
+ void AddServiceOverrideForTesting(
+ const std::string& service_name,
+ const ServiceFactory& service_factory) override;
+ void ClearServiceOverridesForTesting() override;
bool IsBound() const;
base::WeakPtr<ServiceRegistry> GetWeakPtr();
private:
- // mojo::ServiceProvider overrides.
- void ConnectToService(const mojo::String& name,
- mojo::ScopedMessagePipeHandle client_handle) override;
+ // mojo::InterfaceProvider overrides.
+ void GetInterface(const mojo::String& name,
+ mojo::ScopedMessagePipeHandle client_handle) override;
void OnConnectionError();
- mojo::Binding<mojo::ServiceProvider> binding_;
- mojo::ServiceProviderPtr remote_provider_;
+ mojo::Binding<mojo::shell::mojom::InterfaceProvider> binding_;
+ mojo::shell::mojom::InterfaceProviderPtr remote_provider_;
- std::map<std::string, base::Callback<void(mojo::ScopedMessagePipeHandle)> >
- service_factories_;
+ std::map<std::string, ServiceFactory> service_factories_;
std::queue<std::pair<std::string, mojo::MessagePipeHandle> >
pending_connects_;
+ std::map<std::string, ServiceFactory> service_overrides_;
+
base::WeakPtrFactory<ServiceRegistry> weak_factory_;
};
diff --git a/chromium/content/common/mojo/static_loader.cc b/chromium/content/common/mojo/static_loader.cc
new file mode 100644
index 00000000000..107c9135456
--- /dev/null
+++ b/chromium/content/common/mojo/static_loader.cc
@@ -0,0 +1,93 @@
+// Copyright 2015 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 "content/common/mojo/static_loader.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/simple_thread.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/shell/public/cpp/application_runner.h"
+#include "mojo/shell/public/cpp/shell_client.h"
+#include "mojo/shell/public/interfaces/shell_client.mojom.h"
+
+namespace content {
+
+namespace {
+
+class RunnerThread : public base::SimpleThread {
+ public:
+ RunnerThread(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request,
+ scoped_refptr<base::TaskRunner> exit_task_runner,
+ const base::Closure& exit_callback,
+ const StaticLoader::ApplicationFactory& factory)
+ : base::SimpleThread("Mojo Application: " + name),
+ request_(std::move(request)),
+ exit_task_runner_(exit_task_runner),
+ exit_callback_(exit_callback),
+ factory_(factory) {}
+
+ void Run() override {
+ scoped_ptr<mojo::ApplicationRunner> runner(
+ new mojo::ApplicationRunner(factory_.Run().release()));
+ runner->Run(request_.PassMessagePipe().release().value(),
+ false /* init_base */);
+ exit_task_runner_->PostTask(FROM_HERE, exit_callback_);
+ }
+
+ private:
+ mojo::shell::mojom::ShellClientRequest request_;
+ scoped_refptr<base::TaskRunner> exit_task_runner_;
+ base::Closure exit_callback_;
+ StaticLoader::ApplicationFactory factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(RunnerThread);
+};
+
+} // namespace
+
+StaticLoader::StaticLoader(const ApplicationFactory& factory)
+ : StaticLoader(factory, base::Closure()) {
+}
+
+StaticLoader::StaticLoader(const ApplicationFactory& factory,
+ const base::Closure& quit_callback)
+ : factory_(factory), quit_callback_(quit_callback), weak_factory_(this) {
+}
+
+StaticLoader::~StaticLoader() {
+ if (thread_)
+ StopAppThread();
+}
+
+void StaticLoader::Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) {
+ if (thread_)
+ return;
+
+ // If the application's thread quits on its own before this loader dies, we
+ // reset the Thread object, allowing future Load requests to be fulfilled
+ // with a new app instance.
+ auto exit_callback = base::Bind(&StaticLoader::StopAppThread,
+ weak_factory_.GetWeakPtr());
+ thread_.reset(new RunnerThread(name, std::move(request),
+ base::ThreadTaskRunnerHandle::Get(),
+ exit_callback, factory_));
+ thread_->Start();
+}
+
+void StaticLoader::StopAppThread() {
+ thread_->Join();
+ thread_.reset();
+ if (!quit_callback_.is_null())
+ quit_callback_.Run();
+}
+
+} // namespace content
diff --git a/chromium/content/common/mojo/static_loader.h b/chromium/content/common/mojo/static_loader.h
new file mode 100644
index 00000000000..318366d805a
--- /dev/null
+++ b/chromium/content/common/mojo/static_loader.h
@@ -0,0 +1,66 @@
+// Copyright 2015 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 CONTENT_COMMON_MOJO_STATIC_APPLICATION_LOADER_H_
+#define CONTENT_COMMON_MOJO_STATIC_APPLICATION_LOADER_H_
+
+#include <list>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "mojo/shell/loader.h"
+
+namespace base {
+class SimpleThread;
+}
+
+namespace mojo {
+class ShellClient;
+}
+
+namespace content {
+
+// An Loader which loads a single type of app from a given
+// mojo::ShellClientFactory. A Load() request is fulfilled by creating an
+// instance of the app on a new thread. Only one instance of the app will run at
+// a time. Any Load requests received while the app is running will be dropped.
+class StaticLoader : public mojo::shell::Loader {
+ public:
+ using ApplicationFactory = base::Callback<scoped_ptr<mojo::ShellClient>()>;
+
+ // Constructs a static loader for |factory|.
+ explicit StaticLoader(const ApplicationFactory& factory);
+
+ // Constructs a static loader for |factory| with a closure that will be called
+ // when the loaded application quits.
+ StaticLoader(const ApplicationFactory& factory,
+ const base::Closure& quit_callback);
+
+ ~StaticLoader() override;
+
+ // mojo::shell::Loader:
+ void Load(const std::string& name,
+ mojo::shell::mojom::ShellClientRequest request) override;
+
+ private:
+ void StopAppThread();
+
+ // The factory used t create new instances of the application delegate.
+ ApplicationFactory factory_;
+
+ // If not null, this is run when the loaded application quits.
+ base::Closure quit_callback_;
+
+ // Thread for the application if currently running.
+ scoped_ptr<base::SimpleThread> thread_;
+
+ base::WeakPtrFactory<StaticLoader> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticLoader);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_MOJO_STATIC_APPLICATION_LOADER_H_
diff --git a/chromium/content/common/navigation_params.cc b/chromium/content/common/navigation_params.cc
index da6f5901f47..f09cccfebbf 100644
--- a/chromium/content/common/navigation_params.cc
+++ b/chromium/content/common/navigation_params.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/common/url_constants.h"
namespace content {
@@ -14,12 +15,13 @@ namespace content {
bool ShouldMakeNetworkRequestForURL(const GURL& url) {
CHECK(IsBrowserSideNavigationEnabled());
- // Data URLs, Javascript URLs and about:blank should not send a request to the
- // network stack.
+ // Data URLs, Javascript URLs, about:blank, srcdoc should not send a request
+ // to the network stack.
// TODO(clamy): same document navigations should not send requests to the
// network stack. Neither should pushState/popState.
return !url.SchemeIs(url::kDataScheme) && url != GURL(url::kAboutBlankURL) &&
- !url.SchemeIs(url::kJavaScriptScheme);
+ !url.SchemeIs(url::kJavaScriptScheme) && !url.is_empty() &&
+ url != GURL(content::kAboutSrcDocURL);
}
CommonNavigationParams::CommonNavigationParams()
@@ -29,8 +31,8 @@ CommonNavigationParams::CommonNavigationParams()
should_replace_current_entry(false),
report_type(FrameMsg_UILoadMetricsReportType::NO_REPORT),
lofi_state(LOFI_UNSPECIFIED),
- navigation_start(base::TimeTicks::Now()) {
-}
+ navigation_start(base::TimeTicks::Now()),
+ method("GET") {}
CommonNavigationParams::CommonNavigationParams(
const GURL& url,
@@ -44,7 +46,8 @@ CommonNavigationParams::CommonNavigationParams(
const GURL& base_url_for_data_url,
const GURL& history_url_for_data_url,
LoFiState lofi_state,
- const base::TimeTicks& navigation_start)
+ const base::TimeTicks& navigation_start,
+ std::string method)
: url(url),
referrer(referrer),
transition(transition),
@@ -56,8 +59,11 @@ CommonNavigationParams::CommonNavigationParams(
base_url_for_data_url(base_url_for_data_url),
history_url_for_data_url(history_url_for_data_url),
lofi_state(lofi_state),
- navigation_start(navigation_start) {
-}
+ navigation_start(navigation_start),
+ method(method) {}
+
+CommonNavigationParams::CommonNavigationParams(
+ const CommonNavigationParams& other) = default;
CommonNavigationParams::~CommonNavigationParams() {
}
@@ -69,21 +75,22 @@ BeginNavigationParams::BeginNavigationParams()
request_context_type(REQUEST_CONTEXT_TYPE_LOCATION) {}
BeginNavigationParams::BeginNavigationParams(
- std::string method,
std::string headers,
int load_flags,
bool has_user_gesture,
bool skip_service_worker,
RequestContextType request_context_type)
- : method(method),
- headers(headers),
+ : headers(headers),
load_flags(load_flags),
has_user_gesture(has_user_gesture),
skip_service_worker(skip_service_worker),
request_context_type(request_context_type) {}
+BeginNavigationParams::BeginNavigationParams(
+ const BeginNavigationParams& other) = default;
+
StartNavigationParams::StartNavigationParams()
- : is_post(false),
+ :
#if defined(OS_ANDROID)
has_user_gesture(false),
#endif
@@ -92,7 +99,6 @@ StartNavigationParams::StartNavigationParams()
}
StartNavigationParams::StartNavigationParams(
- bool is_post,
const std::string& extra_headers,
const std::vector<unsigned char>& browser_initiated_post_data,
#if defined(OS_ANDROID)
@@ -100,8 +106,7 @@ StartNavigationParams::StartNavigationParams(
#endif
int transferred_request_child_id,
int transferred_request_request_id)
- : is_post(is_post),
- extra_headers(extra_headers),
+ : extra_headers(extra_headers),
browser_initiated_post_data(browser_initiated_post_data),
#if defined(OS_ANDROID)
has_user_gesture(has_user_gesture),
@@ -110,6 +115,9 @@ StartNavigationParams::StartNavigationParams(
transferred_request_request_id(transferred_request_request_id) {
}
+StartNavigationParams::StartNavigationParams(
+ const StartNavigationParams& other) = default;
+
StartNavigationParams::~StartNavigationParams() {
}
@@ -164,6 +172,9 @@ RequestNavigationParams::RequestNavigationParams(
should_create_service_worker(false),
service_worker_provider_id(kInvalidServiceWorkerProviderId) {}
+RequestNavigationParams::RequestNavigationParams(
+ const RequestNavigationParams& other) = default;
+
RequestNavigationParams::~RequestNavigationParams() {
}
diff --git a/chromium/content/common/navigation_params.h b/chromium/content/common/navigation_params.h
index 414319d73e3..d2f83e756c1 100644
--- a/chromium/content/common/navigation_params.h
+++ b/chromium/content/common/navigation_params.h
@@ -59,7 +59,9 @@ struct CONTENT_EXPORT CommonNavigationParams {
const GURL& base_url_for_data_url,
const GURL& history_url_for_data_url,
LoFiState lofi_state,
- const base::TimeTicks& navigation_start);
+ const base::TimeTicks& navigation_start,
+ std::string method);
+ CommonNavigationParams(const CommonNavigationParams& other);
~CommonNavigationParams();
// The URL to navigate to.
@@ -113,6 +115,9 @@ struct CONTENT_EXPORT CommonNavigationParams {
// PlzNavigate: For renderer initiated navigations, this will be set on the
// renderer side and sent with FrameHostMsg_BeginNavigation.
base::TimeTicks navigation_start;
+
+ // The request method: GET, POST, etc.
+ std::string method;
};
// Provided by the renderer ----------------------------------------------------
@@ -128,15 +133,12 @@ struct CONTENT_EXPORT BeginNavigationParams {
// TODO(clamy): See if it is possible to reuse this in
// ResourceMsg_Request_Params.
BeginNavigationParams();
- BeginNavigationParams(std::string method,
- std::string headers,
+ BeginNavigationParams(std::string headers,
int load_flags,
bool has_user_gesture,
bool skip_service_worker,
RequestContextType request_context_type);
-
- // The request method: GET, POST, etc.
- std::string method;
+ BeginNavigationParams(const BeginNavigationParams& other);
// Additional HTTP request headers.
std::string headers;
@@ -171,7 +173,6 @@ struct CONTENT_EXPORT BeginNavigationParams {
struct CONTENT_EXPORT StartNavigationParams {
StartNavigationParams();
StartNavigationParams(
- bool is_post,
const std::string& extra_headers,
const std::vector<unsigned char>& browser_initiated_post_data,
#if defined(OS_ANDROID)
@@ -179,11 +180,9 @@ struct CONTENT_EXPORT StartNavigationParams {
#endif
int transferred_request_child_id,
int transferred_request_request_id);
+ StartNavigationParams(const StartNavigationParams& other);
~StartNavigationParams();
- // Whether the navigation is a POST request (as opposed to a GET).
- bool is_post;
-
// Extra headers (separated by \n) to send during the request.
std::string extra_headers;
@@ -224,6 +223,7 @@ struct CONTENT_EXPORT RequestNavigationParams {
int current_history_list_length,
bool is_view_source,
bool should_clear_history_list);
+ RequestNavigationParams(const RequestNavigationParams& other);
~RequestNavigationParams();
// Whether or not the user agent override string should be used.
diff --git a/chromium/content/common/net/url_request_service_worker_data.cc b/chromium/content/common/net/url_request_service_worker_data.cc
new file mode 100644
index 00000000000..cbf2a875494
--- /dev/null
+++ b/chromium/content/common/net/url_request_service_worker_data.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 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 "content/common/net/url_request_service_worker_data.h"
+
+namespace content {
+
+URLRequestServiceWorkerData::URLRequestServiceWorkerData() {}
+
+URLRequestServiceWorkerData::~URLRequestServiceWorkerData() {}
+
+// static
+const void* URLRequestServiceWorkerData::kUserDataKey =
+ static_cast<const void*>(&URLRequestServiceWorkerData::kUserDataKey);
+
+} // namespace content
diff --git a/chromium/content/common/net/url_request_service_worker_data.h b/chromium/content/common/net/url_request_service_worker_data.h
new file mode 100644
index 00000000000..4d72321d0a6
--- /dev/null
+++ b/chromium/content/common/net/url_request_service_worker_data.h
@@ -0,0 +1,28 @@
+// Copyright 2016 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 CONTENT_COMMON_NET_URL_REQUEST_SERVICE_WORKER_DATA_H_
+#define CONTENT_COMMON_NET_URL_REQUEST_SERVICE_WORKER_DATA_H_
+
+#include "base/supports_user_data.h"
+
+namespace content {
+
+// Used to annotate all URLRequests for which the request originated in the
+// Service Worker and for initial Service Worker script loads.
+// Summarized this includes requests due to:
+// - fetching Service Worker script itself for installation,
+// - importing other scripts from within a Service Worker script,
+// - calling fetch() from within a Service Worker script.
+class URLRequestServiceWorkerData : public base::SupportsUserData::Data {
+ public:
+ URLRequestServiceWorkerData();
+ ~URLRequestServiceWorkerData() override;
+
+ static const void* kUserDataKey;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_NET_URL_REQUEST_SERVICE_WORKER_DATA_H_
diff --git a/chromium/content/common/notification_constants.h b/chromium/content/common/notification_constants.h
index 6ca8ad62e59..2573a6eb8f8 100644
--- a/chromium/content/common/notification_constants.h
+++ b/chromium/content/common/notification_constants.h
@@ -12,6 +12,18 @@ namespace content {
// Maximum number of actions on a Platform Notification.
static const size_t kPlatformNotificationMaxActions = 2;
+// The maximum reasonable notification icon size, scaled from dip units to
+// pixels using the largest supported scaling factor.
+static const int kPlatformNotificationMaxIconSizePx = 320; // 80 dip * 4
+
+// The maximum reasonable badge size, scaled from dip units to pixels using the
+// largest supported scaling factor.
+static const int kPlatformNotificationMaxBadgeSizePx = 96; // 24 dip * 4
+
+// The maximum reasonable action icon size, scaled from dip units to
+// pixels using the largest supported scaling factor.
+static const int kPlatformNotificationMaxActionIconSizePx = 128; // 32 dip * 4
+
} // namespace content
#endif // CONTENT_COMMON_NOTIFICATION_CONSTANTS_H_
diff --git a/chromium/content/common/one_writer_seqlock_unittest.cc b/chromium/content/common/one_writer_seqlock_unittest.cc
index 8e69812c9e2..84d5156a7bd 100644
--- a/chromium/content/common/one_writer_seqlock_unittest.cc
+++ b/chromium/content/common/one_writer_seqlock_unittest.cc
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
@@ -60,7 +61,12 @@ class BasicSeqLockTestThread : public PlatformThread::Delegate {
DISALLOW_COPY_AND_ASSIGN(BasicSeqLockTestThread);
};
-TEST(OneWriterSeqLockTest, ManyThreads) {
+#if defined(OS_ANDROID)
+#define MAYBE_ManyThreads FLAKY_ManyThreads
+#else
+#define MAYBE_ManyThreads ManyThreads
+#endif
+TEST(OneWriterSeqLockTest, MAYBE_ManyThreads) {
content::OneWriterSeqLock seqlock;
TestData data = { 0, 0, 0 };
base::AtomicRefCount ready = 0;
diff --git a/chromium/content/common/origin_trials/trial_token.cc b/chromium/content/common/origin_trials/trial_token.cc
new file mode 100644
index 00000000000..0a137edc68b
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token.cc
@@ -0,0 +1,193 @@
+// Copyright 2015 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 "content/common/origin_trials/trial_token.h"
+
+#include <openssl/curve25519.h>
+
+#include <vector>
+
+#include "base/base64.h"
+#include "base/big_endian.h"
+#include "base/json/json_reader.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace {
+
+// Version is a 1-byte field at offset 0.
+const size_t kVersionOffset = 0;
+const size_t kVersionSize = 1;
+
+// These constants define the Version 2 field sizes and offsets.
+const size_t kSignatureOffset = kVersionOffset + kVersionSize;
+const size_t kSignatureSize = 64;
+const size_t kPayloadLengthOffset = kSignatureOffset + kSignatureSize;
+const size_t kPayloadLengthSize = 4;
+const size_t kPayloadOffset = kPayloadLengthOffset + kPayloadLengthSize;
+
+// Version 2 is the only token version currently supported. Version 1 was
+// introduced in Chrome M50, and removed in M51. There were no experiments
+// enabled in the stable M50 release which would have used those tokens.
+const uint8_t kVersion2 = 2;
+
+} // namespace
+
+TrialToken::~TrialToken() {}
+
+// static
+std::unique_ptr<TrialToken> TrialToken::From(const std::string& token_text,
+ base::StringPiece public_key) {
+ std::unique_ptr<std::string> token_payload = Extract(token_text, public_key);
+ if (!token_payload) {
+ return nullptr;
+ }
+ return Parse(*token_payload);
+}
+
+bool TrialToken::IsValidForFeature(const url::Origin& origin,
+ base::StringPiece feature_name,
+ const base::Time& now) const {
+ return ValidateOrigin(origin) && ValidateFeatureName(feature_name) &&
+ ValidateDate(now);
+}
+
+std::unique_ptr<std::string> TrialToken::Extract(
+ const std::string& token_payload,
+ base::StringPiece public_key) {
+ if (token_payload.empty()) {
+ return nullptr;
+ }
+
+ // Token is base64-encoded; decode first.
+ std::string token_contents;
+ if (!base::Base64Decode(token_payload, &token_contents)) {
+ return nullptr;
+ }
+
+ // Only version 2 currently supported.
+ if (token_contents.length() < (kVersionOffset + kVersionSize)) {
+ return nullptr;
+ }
+ uint8_t version = token_contents[kVersionOffset];
+ if (version != kVersion2) {
+ return nullptr;
+ }
+
+ // Token must be large enough to contain a version, signature, and payload
+ // length.
+ if (token_contents.length() < (kPayloadLengthOffset + kPayloadLengthSize)) {
+ return nullptr;
+ }
+
+ // Extract the length of the signed data (Big-endian).
+ uint32_t payload_length;
+ base::ReadBigEndian(&(token_contents[kPayloadLengthOffset]), &payload_length);
+
+ // Validate that the stated length matches the actual payload length.
+ if (payload_length != token_contents.length() - kPayloadOffset) {
+ return nullptr;
+ }
+
+ // Extract the version-specific contents of the token.
+ const char* token_bytes = token_contents.data();
+ base::StringPiece version_piece(token_bytes + kVersionOffset, kVersionSize);
+ base::StringPiece signature(token_bytes + kSignatureOffset, kSignatureSize);
+ base::StringPiece payload_piece(token_bytes + kPayloadLengthOffset,
+ kPayloadLengthSize + payload_length);
+
+ // The data which is covered by the signature is (version + length + payload).
+ std::string signed_data =
+ version_piece.as_string() + payload_piece.as_string();
+
+ // Validate the signature on the data before proceeding.
+ if (!TrialToken::ValidateSignature(signature, signed_data, public_key)) {
+ return nullptr;
+ }
+
+ // Return just the payload, as a new string.
+ return base::WrapUnique(
+ new std::string(token_contents, kPayloadOffset, payload_length));
+}
+
+std::unique_ptr<TrialToken> TrialToken::Parse(const std::string& token_json) {
+ std::unique_ptr<base::DictionaryValue> datadict =
+ base::DictionaryValue::From(base::JSONReader::Read(token_json));
+ if (!datadict) {
+ return nullptr;
+ }
+
+ std::string origin_string;
+ std::string feature_name;
+ int expiry_timestamp = 0;
+ datadict->GetString("origin", &origin_string);
+ datadict->GetString("feature", &feature_name);
+ datadict->GetInteger("expiry", &expiry_timestamp);
+
+ // Ensure that the origin is a valid (non-unique) origin URL.
+ url::Origin origin = url::Origin(GURL(origin_string));
+ if (origin.unique()) {
+ return nullptr;
+ }
+
+ // Ensure that the feature name is a valid string.
+ if (feature_name.empty()) {
+ return nullptr;
+ }
+
+ // Ensure that the expiry timestamp is a valid (positive) integer.
+ if (expiry_timestamp <= 0) {
+ return nullptr;
+ }
+
+ return base::WrapUnique(
+ new TrialToken(origin, feature_name, expiry_timestamp));
+}
+
+bool TrialToken::ValidateOrigin(const url::Origin& origin) const {
+ return origin == origin_;
+}
+
+bool TrialToken::ValidateFeatureName(base::StringPiece feature_name) const {
+ return feature_name == feature_name_;
+}
+
+bool TrialToken::ValidateDate(const base::Time& now) const {
+ return expiry_time_ > now;
+}
+
+// static
+bool TrialToken::ValidateSignature(base::StringPiece signature,
+ const std::string& data,
+ base::StringPiece public_key) {
+ // Public key must be 32 bytes long for Ed25519.
+ CHECK_EQ(public_key.length(), 32UL);
+
+ // Signature must be 64 bytes long.
+ if (signature.length() != 64) {
+ return false;
+ }
+
+ int result = ED25519_verify(
+ reinterpret_cast<const uint8_t*>(data.data()), data.length(),
+ reinterpret_cast<const uint8_t*>(signature.data()),
+ reinterpret_cast<const uint8_t*>(public_key.data()));
+ return (result != 0);
+}
+
+TrialToken::TrialToken(const url::Origin& origin,
+ const std::string& feature_name,
+ uint64_t expiry_timestamp)
+ : origin_(origin),
+ feature_name_(feature_name),
+ expiry_time_(base::Time::FromDoubleT(expiry_timestamp)) {}
+
+} // namespace content
diff --git a/chromium/content/common/origin_trials/trial_token.h b/chromium/content/common/origin_trials/trial_token.h
new file mode 100644
index 00000000000..fa05e3713b5
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token.h
@@ -0,0 +1,90 @@
+// Copyright 2015 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 CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_H_
+#define CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_H_
+
+#include <memory>
+#include <string>
+
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+
+// The Experimental Framework (EF) provides limited access to experimental
+// features, on a per-origin basis (origin trials). This class defines the trial
+// token data structure, used to securely provide access to an experimental
+// feature.
+//
+// Features are defined by string names, provided by the implementers. The EF
+// code does not maintain an enum or constant list for feature names. Instead,
+// the EF validates the name provided by the feature implementation against any
+// provided tokens.
+//
+// More documentation on the token format can be found at
+// https://docs.google.com/document/d/1v5fi0EUV_QHckVHVF2K4P72iNywnrJtNhNZ6i2NPt0M
+
+class CONTENT_EXPORT TrialToken {
+ public:
+ ~TrialToken();
+
+ // Returns a token object if the string represents a signed well-formed token,
+ // or nullptr otherwise. (This does not mean that the token is currently
+ // valid, or appropriate for a given origin / feature, just that it is
+ // correctly formatted and signed by the supplied public key, and can be
+ // parsed.)
+ static std::unique_ptr<TrialToken> From(const std::string& token_text,
+ base::StringPiece public_key);
+
+ // Returns true if this token is appropriate for use by the given origin,
+ // for the given feature name, and has not yet expired.
+ bool IsValidForFeature(const url::Origin& origin,
+ base::StringPiece feature_name,
+ const base::Time& now) const;
+
+ url::Origin origin() { return origin_; }
+ std::string feature_name() { return feature_name_; }
+ base::Time expiry_time() { return expiry_time_; }
+
+ protected:
+ friend class TrialTokenTest;
+
+ // Returns the payload of a signed token, or nullptr if the token is not
+ // properly signed, or is not well-formed.
+ static std::unique_ptr<std::string> Extract(const std::string& token_text,
+ base::StringPiece public_key);
+
+ // Returns a token object if the string represents a well-formed JSON token
+ // payload, or nullptr otherwise.
+ static std::unique_ptr<TrialToken> Parse(const std::string& token_json);
+
+ bool ValidateOrigin(const url::Origin& origin) const;
+ bool ValidateFeatureName(base::StringPiece feature_name) const;
+ bool ValidateDate(const base::Time& now) const;
+
+ static bool ValidateSignature(base::StringPiece signature_text,
+ const std::string& data,
+ base::StringPiece public_key);
+
+ private:
+ TrialToken(const url::Origin& origin,
+ const std::string& feature_name,
+ uint64_t expiry_timestamp);
+
+ // The origin for which this token is valid. Must be a secure origin.
+ url::Origin origin_;
+
+ // The name of the experimental feature which this token enables.
+ std::string feature_name_;
+
+ // The time until which this token should be considered valid.
+ base::Time expiry_time_;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_H_
diff --git a/chromium/content/common/origin_trials/trial_token_unittest.cc b/chromium/content/common/origin_trials/trial_token_unittest.cc
new file mode 100644
index 00000000000..ebb5b05a4cf
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token_unittest.cc
@@ -0,0 +1,300 @@
+// Copyright 2015 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 "content/common/origin_trials/trial_token.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "base/test/simple_test_clock.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+// This is a sample public key for testing the API. The corresponding private
+// key (use this to generate new samples for this test file) is:
+//
+// 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13,
+// 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba,
+// 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75,
+// 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a,
+// 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64,
+// 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0
+const uint8_t kTestPublicKey[] = {
+ 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
+ 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
+ 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
+};
+
+// This is a valid, but incorrect, public key for testing signatures against.
+// The corresponding private key is:
+//
+// 0x21, 0xee, 0xfa, 0x81, 0x6a, 0xff, 0xdf, 0xb8, 0xc1, 0xdd, 0x75,
+// 0x05, 0x04, 0x29, 0x68, 0x67, 0x60, 0x85, 0x91, 0xd0, 0x50, 0x16,
+// 0x0a, 0xcf, 0xa2, 0x37, 0xa3, 0x2e, 0x11, 0x7a, 0x17, 0x96, 0x50,
+// 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c, 0x47,
+// 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51, 0x3e,
+// 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca
+const uint8_t kTestPublicKey2[] = {
+ 0x50, 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c,
+ 0x47, 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51,
+ 0x3e, 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca,
+};
+
+// This is a good trial token, signed with the above test private key.
+// Generate this token with the command (in tools/origin_trials):
+// generate_token.py valid.example.com Frobulate --expire-timestamp=1458766277
+const char* kSampleToken =
+ "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj"
+ "7FO5L22sNvkZZnacLvmfNwsAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMTQ1ODc2NjI3N30=";
+
+const char* kExpectedFeatureName = "Frobulate";
+const char* kExpectedOrigin = "https://valid.example.com";
+const uint64_t kExpectedExpiry = 1458766277;
+
+// The token should not be valid for this origin, or for this feature.
+const char* kInvalidOrigin = "https://invalid.example.com";
+const char* kInsecureOrigin = "http://valid.example.com";
+const char* kInvalidFeatureName = "Grokalyze";
+
+// The token should be valid if the current time is kValidTimestamp or earlier.
+double kValidTimestamp = 1458766276.0;
+
+// The token should be invalid if the current time is kInvalidTimestamp or
+// later.
+double kInvalidTimestamp = 1458766278.0;
+
+// Well-formed trial token with an invalid signature.
+const char* kInvalidSignatureToken =
+ "AYeNXSDktgG9p4ns5B1WKsLq2TytMxfR4whfbi+oyT0rXyzh+qXYfxbDMGmyjU2Z"
+ "lEJ16vQObMXJoOaYUqd8xwkAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMTQ1ODc2NjI3N30=";
+
+// Trial token truncated in the middle of the length field; too short to
+// possibly be valid.
+const char kTruncatedToken[] =
+ "Ap+Q/Qm0ELadZql+dlEGSwnAVsFZKgCEtUZg8idQC3uekkIeSZIY1tftoYdrwhqj"
+ "7FO5L22sNvkZZnacLvmfNwsA";
+
+// Trial token with an incorrectly-declared length, but with a valid signature.
+const char kIncorrectLengthToken[] =
+ "Ao06eNl/CZuM88qurWKX4RfoVEpHcVHWxdOTrEXZkaC1GUHyb/8L4sthADiVWdc9"
+ "kXFyF1BW5bbraqp6MBVr3wEAAABaeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMTQ1ODc2NjI3N30=";
+
+// Trial token with a misidentified version (42).
+const char kIncorrectVersionToken[] =
+ "KlH8wVLT5o59uDvlJESorMDjzgWnvG1hmIn/GiT9Ng3f45ratVeiXCNTeaJheOaG"
+ "A6kX4ir4Amv8aHVC+OJHZQkAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMTQ1ODc2NjI3N30=";
+
+const char kSampleTokenJSON[] =
+ "{\"origin\": \"https://valid.example.com:443\", \"feature\": "
+ "\"Frobulate\", \"expiry\": 1458766277}";
+
+// Various ill-formed trial tokens. These should all fail to parse.
+const char* kInvalidTokens[] = {
+ // Invalid - Not JSON at all
+ "abcde",
+ // Invalid JSON
+ "{",
+ // Not an object
+ "\"abcde\"",
+ "123.4",
+ "[0, 1, 2]",
+ // Missing keys
+ "{}",
+ "{\"something\": 1}",
+ "{\"origin\": \"https://a.a\"}",
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\"}"
+ "{\"origin\": \"https://a.a\", \"expiry\": 1458766277}",
+ "{\"feature\": \"FeatureName\", \"expiry\": 1458766277}",
+ // Incorrect types
+ "{\"origin\": 1, \"feature\": \"a\", \"expiry\": 1458766277}",
+ "{\"origin\": \"https://a.a\", \"feature\": 1, \"expiry\": 1458766277}",
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\", \"expiry\": \"1\"}",
+ // Negative expiry timestamp
+ "{\"origin\": \"https://a.a\", \"feature\": \"a\", \"expiry\": -1}",
+ // Origin not a proper origin URL
+ "{\"origin\": \"abcdef\", \"feature\": \"a\", \"expiry\": 1458766277}",
+ "{\"origin\": \"data:text/plain,abcdef\", \"feature\": \"a\", \"expiry\": "
+ "1458766277}",
+ "{\"origin\": \"javascript:alert(1)\", \"feature\": \"a\", \"expiry\": "
+ "1458766277}"};
+
+} // namespace
+
+class TrialTokenTest : public testing::TestWithParam<const char*> {
+ public:
+ TrialTokenTest()
+ : expected_origin_(GURL(kExpectedOrigin)),
+ invalid_origin_(GURL(kInvalidOrigin)),
+ insecure_origin_(GURL(kInsecureOrigin)),
+ expected_expiry_(base::Time::FromDoubleT(kExpectedExpiry)),
+ valid_timestamp_(base::Time::FromDoubleT(kValidTimestamp)),
+ invalid_timestamp_(base::Time::FromDoubleT(kInvalidTimestamp)),
+ correct_public_key_(
+ base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
+ arraysize(kTestPublicKey))),
+ incorrect_public_key_(
+ base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey2),
+ arraysize(kTestPublicKey2))) {}
+
+ protected:
+ std::unique_ptr<std::string> Extract(const std::string& token_text,
+ base::StringPiece public_key) {
+ return TrialToken::Extract(token_text, public_key);
+ }
+ std::unique_ptr<TrialToken> Parse(const std::string& token_payload) {
+ return TrialToken::Parse(token_payload);
+ }
+
+ bool ValidateOrigin(TrialToken* token, const url::Origin origin) {
+ return token->ValidateOrigin(origin);
+ }
+
+ bool ValidateFeatureName(TrialToken* token, const char* feature_name) {
+ return token->ValidateFeatureName(feature_name);
+ }
+
+ bool ValidateDate(TrialToken* token, const base::Time& now) {
+ return token->ValidateDate(now);
+ }
+
+ base::StringPiece correct_public_key() { return correct_public_key_; }
+ base::StringPiece incorrect_public_key() { return incorrect_public_key_; }
+
+ const url::Origin expected_origin_;
+ const url::Origin invalid_origin_;
+ const url::Origin insecure_origin_;
+
+ const base::Time expected_expiry_;
+ const base::Time valid_timestamp_;
+ const base::Time invalid_timestamp_;
+
+ private:
+ base::StringPiece correct_public_key_;
+ base::StringPiece incorrect_public_key_;
+};
+
+// Test the extraction of the signed payload from token strings. This includes
+// checking the included version identifier, payload length, and cryptographic
+// signature.
+
+// Test verification of signature and extraction of token JSON from signed
+// token.
+TEST_F(TrialTokenTest, ValidateValidSignature) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kSampleToken, correct_public_key());
+ ASSERT_TRUE(token_payload);
+ EXPECT_STREQ(kSampleTokenJSON, token_payload.get()->c_str());
+}
+
+TEST_F(TrialTokenTest, ValidateInvalidSignature) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kInvalidSignatureToken, correct_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectKey) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kSampleToken, incorrect_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+TEST_F(TrialTokenTest, ValidateEmptyToken) {
+ std::unique_ptr<std::string> token_payload =
+ Extract("", correct_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+TEST_F(TrialTokenTest, ValidateShortToken) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kTruncatedToken, correct_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+TEST_F(TrialTokenTest, ValidateUnsupportedVersion) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kIncorrectVersionToken, correct_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+TEST_F(TrialTokenTest, ValidateSignatureWithIncorrectLength) {
+ std::unique_ptr<std::string> token_payload =
+ Extract(kIncorrectLengthToken, correct_public_key());
+ ASSERT_FALSE(token_payload);
+}
+
+// Test parsing of fields from JSON token.
+
+TEST_F(TrialTokenTest, ParseEmptyString) {
+ std::unique_ptr<TrialToken> empty_token = Parse("");
+ EXPECT_FALSE(empty_token);
+}
+
+TEST_P(TrialTokenTest, ParseInvalidString) {
+ std::unique_ptr<TrialToken> empty_token = Parse(GetParam());
+ EXPECT_FALSE(empty_token) << "Invalid trial token should not parse.";
+}
+
+INSTANTIATE_TEST_CASE_P(, TrialTokenTest, ::testing::ValuesIn(kInvalidTokens));
+
+TEST_F(TrialTokenTest, ParseValidToken) {
+ std::unique_ptr<TrialToken> token = Parse(kSampleTokenJSON);
+ ASSERT_TRUE(token);
+ EXPECT_EQ(kExpectedFeatureName, token->feature_name());
+ EXPECT_EQ(expected_origin_, token->origin());
+ EXPECT_EQ(expected_expiry_, token->expiry_time());
+}
+
+TEST_F(TrialTokenTest, ValidateValidToken) {
+ std::unique_ptr<TrialToken> token = Parse(kSampleTokenJSON);
+ ASSERT_TRUE(token);
+ EXPECT_TRUE(ValidateOrigin(token.get(), expected_origin_));
+ EXPECT_FALSE(ValidateOrigin(token.get(), invalid_origin_));
+ EXPECT_FALSE(ValidateOrigin(token.get(), insecure_origin_));
+ EXPECT_TRUE(ValidateFeatureName(token.get(), kExpectedFeatureName));
+ EXPECT_FALSE(ValidateFeatureName(token.get(), kInvalidFeatureName));
+ EXPECT_FALSE(ValidateFeatureName(
+ token.get(), base::ToUpperASCII(kExpectedFeatureName).c_str()));
+ EXPECT_FALSE(ValidateFeatureName(
+ token.get(), base::ToLowerASCII(kExpectedFeatureName).c_str()));
+ EXPECT_TRUE(ValidateDate(token.get(), valid_timestamp_));
+ EXPECT_FALSE(ValidateDate(token.get(), invalid_timestamp_));
+}
+
+TEST_F(TrialTokenTest, TokenIsValidForFeature) {
+ std::unique_ptr<TrialToken> token = Parse(kSampleTokenJSON);
+ ASSERT_TRUE(token);
+ EXPECT_TRUE(token->IsValidForFeature(expected_origin_, kExpectedFeatureName,
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(
+ expected_origin_, base::ToUpperASCII(kExpectedFeatureName),
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(
+ expected_origin_, base::ToLowerASCII(kExpectedFeatureName),
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(invalid_origin_, kExpectedFeatureName,
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(insecure_origin_, kExpectedFeatureName,
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(expected_origin_, kInvalidFeatureName,
+ valid_timestamp_));
+ EXPECT_FALSE(token->IsValidForFeature(expected_origin_, kExpectedFeatureName,
+ invalid_timestamp_));
+}
+
+} // namespace content
diff --git a/chromium/content/common/origin_trials/trial_token_validator.cc b/chromium/content/common/origin_trials/trial_token_validator.cc
new file mode 100644
index 00000000000..6eef75a5e9a
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token_validator.cc
@@ -0,0 +1,30 @@
+// Copyright 2016 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 "content/common/origin_trials/trial_token_validator.h"
+
+#include "base/time/time.h"
+#include "content/common/origin_trials/trial_token.h"
+#include "content/public/common/content_client.h"
+
+namespace content {
+
+bool TrialTokenValidator::ValidateToken(const std::string& token,
+ const url::Origin& origin,
+ base::StringPiece feature_name) {
+ // TODO(iclelland): Allow for multiple signing keys, and iterate over all
+ // active keys here. https://crbug.com/543220
+ ContentClient* content_client = GetContentClient();
+ base::StringPiece public_key = content_client->GetOriginTrialPublicKey();
+ if (public_key.empty()) {
+ return false;
+ }
+ std::unique_ptr<TrialToken> trial_token = TrialToken::From(token, public_key);
+
+ return trial_token &&
+ trial_token->IsValidForFeature(origin, feature_name,
+ base::Time::Now());
+}
+
+} // namespace content
diff --git a/chromium/content/common/origin_trials/trial_token_validator.h b/chromium/content/common/origin_trials/trial_token_validator.h
new file mode 100644
index 00000000000..a8406350d71
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token_validator.h
@@ -0,0 +1,26 @@
+// Copyright 2016 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 CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_VALIDATOR_H_
+#define CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_VALIDATOR_H_
+
+#include <string>
+#include "base/strings/string_piece.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace TrialTokenValidator {
+
+// This method is thread-safe.
+CONTENT_EXPORT bool ValidateToken(const std::string& token,
+ const url::Origin& origin,
+ base::StringPiece feature_name);
+
+} // namespace TrialTokenValidator
+
+} // namespace content
+
+#endif // CONTENT_COMMON_ORIGIN_TRIALS_TRIAL_TOKEN_VALIDATOR_H_
diff --git a/chromium/content/common/origin_trials/trial_token_validator_unittest.cc b/chromium/content/common/origin_trials/trial_token_validator_unittest.cc
new file mode 100644
index 00000000000..59011e785f2
--- /dev/null
+++ b/chromium/content/common/origin_trials/trial_token_validator_unittest.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 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 "content/common/origin_trials/trial_token_validator.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/strings/string_util.h"
+#include "base/test/simple_test_clock.h"
+#include "base/time/time.h"
+#include "content/public/common/content_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+// This is a sample public key for testing the API. The corresponding private
+// key (use this to generate new samples for this test file) is:
+//
+// 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13,
+// 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba,
+// 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75,
+// 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a,
+// 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64,
+// 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0
+const uint8_t kTestPublicKey[] = {
+ 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
+ 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
+ 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
+};
+
+// 0x21, 0xee, 0xfa, 0x81, 0x6a, 0xff, 0xdf, 0xb8, 0xc1, 0xdd, 0x75,
+// 0x05, 0x04, 0x29, 0x68, 0x67, 0x60, 0x85, 0x91, 0xd0, 0x50, 0x16,
+// 0x0a, 0xcf, 0xa2, 0x37, 0xa3, 0x2e, 0x11, 0x7a, 0x17, 0x96, 0x50,
+// 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c, 0x47,
+// 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51, 0x3e,
+// 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca
+const uint8_t kTestPublicKey2[] = {
+ 0x50, 0x07, 0x4d, 0x76, 0x55, 0x56, 0x42, 0x17, 0x2d, 0x8a, 0x9c,
+ 0x47, 0x96, 0x25, 0xda, 0x70, 0xaa, 0xb9, 0xfd, 0x53, 0x5d, 0x51,
+ 0x3e, 0x16, 0xab, 0xb4, 0x86, 0xea, 0xf3, 0x35, 0xc6, 0xca,
+};
+
+// This is a good trial token, signed with the above test private key.
+// TODO(iclelland): This token expires in 2033. Update it or find a way
+// to autogenerate it before then.
+// Generate this token with the command (in tools/origin_trials):
+// generate_token.py valid.example.com Frobulate --expire-timestamp=2000000000
+const char kSampleToken[] =
+ "AuR/1mg+/w5ROLN54Ok20rApK3opgR7Tq9ZfzhATQmnCa+BtPA1RRw4Nigf336r+"
+ "O4fM3Sa+MEd+5JcIgSZafw8AAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMjAwMDAwMDAwMH0=";
+
+// The token should be valid for this origin and for this feature.
+const char kAppropriateOrigin[] = "https://valid.example.com";
+const char kAppropriateFeatureName[] = "Frobulate";
+
+const char kInappropriateFeatureName[] = "Grokalyze";
+const char kInappropriateOrigin[] = "https://invalid.example.com";
+const char kInsecureOrigin[] = "http://valid.example.com";
+
+// Well-formed trial token with an invalid signature.
+// This token is a corruption of the above valid token.
+const char kInvalidSignatureToken[] =
+ "AuR/1mg+/w5ROLN54Ok20rApK3opgR7Tq9ZfzhATQmnCa+BtPA1RRw4Nigf336r+"
+ "RrOtlAwa0gPqqn+A8GTD3AQAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMjAwMDAwMDAwMH0=";
+
+// Well-formed, but expired, trial token. (Expired in 2001)
+// Generate this token with the command (in tools/origin_trials):
+// generate_token.py valid.example.com Frobulate --expire-timestamp=1000000000
+const char kExpiredToken[] =
+ "AmHPUIXMaXe9jWW8kJeDFXolVjT93p4XMnK4+jMYd2pjqtFcYB1bUmdD8PunQKM+"
+ "RrOtlAwa0gPqqn+A8GTD3AQAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
+ "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
+ "IjogMTAwMDAwMDAwMH0=";
+
+const char kUnparsableToken[] = "abcde";
+
+class TestContentClient : public ContentClient {
+ public:
+ base::StringPiece GetOriginTrialPublicKey() override {
+ return base::StringPiece(reinterpret_cast<const char*>(key_),
+ arraysize(kTestPublicKey));
+ }
+ void SetOriginTrialPublicKey(const uint8_t* key) { key_ = key; }
+ const uint8_t* key_ = nullptr;
+};
+
+} // namespace
+
+class TrialTokenValidatorTest : public testing::Test {
+ public:
+ TrialTokenValidatorTest()
+ : appropriate_origin_(GURL(kAppropriateOrigin)),
+ inappropriate_origin_(GURL(kInappropriateOrigin)),
+ insecure_origin_(GURL(kInsecureOrigin)) {
+ SetPublicKey(kTestPublicKey);
+ SetContentClient(&test_content_client_);
+ }
+
+ ~TrialTokenValidatorTest() override { SetContentClient(nullptr); }
+
+ void SetPublicKey(const uint8_t* key) {
+ test_content_client_.SetOriginTrialPublicKey(key);
+ }
+
+ const url::Origin appropriate_origin_;
+ const url::Origin inappropriate_origin_;
+ const url::Origin insecure_origin_;
+
+ private:
+ TestContentClient test_content_client_;
+};
+
+TEST_F(TrialTokenValidatorTest, ValidateValidToken) {
+ EXPECT_TRUE(TrialTokenValidator::ValidateToken(
+ kSampleToken, appropriate_origin_, kAppropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateInappropriateOrigin) {
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kSampleToken, inappropriate_origin_, kAppropriateFeatureName));
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kSampleToken, insecure_origin_, kAppropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateInappropriateFeature) {
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kSampleToken, appropriate_origin_, kInappropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateInvalidSignature) {
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kInvalidSignatureToken, appropriate_origin_, kAppropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateUnparsableToken) {
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kUnparsableToken, appropriate_origin_, kAppropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateExpiredToken) {
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kExpiredToken, appropriate_origin_, kAppropriateFeatureName));
+}
+
+TEST_F(TrialTokenValidatorTest, ValidateValidTokenWithIncorrectKey) {
+ SetPublicKey(kTestPublicKey2);
+ EXPECT_FALSE(TrialTokenValidator::ValidateToken(
+ kSampleToken, appropriate_origin_, kAppropriateFeatureName));
+}
+
+} // namespace content
diff --git a/chromium/content/common/origin_util.cc b/chromium/content/common/origin_util.cc
index 9c6b6310f22..4dfdc6ce8ca 100644
--- a/chromium/content/common/origin_util.cc
+++ b/chromium/content/common/origin_util.cc
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/stl_util.h"
#include "content/public/common/content_client.h"
-#include "net/base/net_util.h"
+#include "net/base/url_util.h"
#include "url/gurl.h"
namespace content {
diff --git a/chromium/content/common/p2p_messages.h b/chromium/content/common/p2p_messages.h
index 24daee51f07..9725b257cff 100644
--- a/chromium/content/common/p2p_messages.h
+++ b/chromium/content/common/p2p_messages.h
@@ -11,6 +11,7 @@
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "ipc/ipc_message_macros.h"
+#include "net/base/ip_address.h"
#include "net/base/network_interfaces.h"
#include "third_party/webrtc/base/asyncpacketsocket.h"
@@ -62,8 +63,8 @@ IPC_STRUCT_TRAITS_END()
IPC_MESSAGE_CONTROL3(P2PMsg_NetworkListChanged,
net::NetworkInterfaceList /* networks */,
- net::IPAddressNumber /* default_ipv4_local_address */,
- net::IPAddressNumber /* default_ipv6_local_address */)
+ net::IPAddress /* default_ipv4_local_address */,
+ net::IPAddress /* default_ipv6_local_address */)
IPC_MESSAGE_CONTROL2(P2PMsg_GetHostAddressResult,
int32_t /* request_id */,
diff --git a/chromium/content/common/page_messages.h b/chromium/content/common/page_messages.h
new file mode 100644
index 00000000000..284c134508b
--- /dev/null
+++ b/chromium/content/common/page_messages.h
@@ -0,0 +1,25 @@
+// Copyright 2016 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 "ipc/ipc_message_macros.h"
+
+// IPC messages for page-level actions.
+// Multiply-included message file, hence no include guard.
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+
+#define IPC_MESSAGE_START PageMsgStart
+
+// Messages sent from the browser to the renderer.
+
+IPC_MESSAGE_ROUTED1(PageMsg_UpdateWindowScreenRect,
+ gfx::Rect /* window_screen_rect */)
+
+// -----------------------------------------------------------------------------
+// Messages sent from the renderer to the browser.
+
+// Adding a new message? Stick to the sort order above: first platform
+// independent PageMsg, then ifdefs for platform specific PageMsg, then platform
+// independent PageHostMsg, then ifdefs for platform specific PageHostMsg.
diff --git a/chromium/content/common/page_state_serialization.cc b/chromium/content/common/page_state_serialization.cc
index 53ddf098d16..b9670c2f244 100644
--- a/chromium/content/common/page_state_serialization.cc
+++ b/chromium/content/common/page_state_serialization.cc
@@ -606,8 +606,7 @@ void ReadFrameState(SerializeObject* obj, bool is_top,
float device_scale_factor = g_device_scale_factor_for_testing;
if (!device_scale_factor) {
device_scale_factor =
- gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().
- device_scale_factor();
+ gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
}
state->scroll_offset =
gfx::Point(state->scroll_offset.x() / state->page_scale_factor,
@@ -672,6 +671,9 @@ ExplodedHttpBodyElement::ExplodedHttpBodyElement()
file_modification_time(std::numeric_limits<double>::quiet_NaN()) {
}
+ExplodedHttpBodyElement::ExplodedHttpBodyElement(
+ const ExplodedHttpBodyElement& other) = default;
+
ExplodedHttpBodyElement::~ExplodedHttpBodyElement() {
}
diff --git a/chromium/content/common/page_state_serialization.h b/chromium/content/common/page_state_serialization.h
index 9b6773c2303..24d81981ef8 100644
--- a/chromium/content/common/page_state_serialization.h
+++ b/chromium/content/common/page_state_serialization.h
@@ -32,6 +32,7 @@ struct CONTENT_EXPORT ExplodedHttpBodyElement {
std::string blob_uuid;
ExplodedHttpBodyElement();
+ ExplodedHttpBodyElement(const ExplodedHttpBodyElement& other);
~ExplodedHttpBodyElement();
};
diff --git a/chromium/content/common/pepper_plugin_list.cc b/chromium/content/common/pepper_plugin_list.cc
index ea24ff7eb97..610670e20b2 100644
--- a/chromium/content/common/pepper_plugin_list.cc
+++ b/chromium/content/common/pepper_plugin_list.cc
@@ -54,7 +54,8 @@ void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
// plugin-entry =
// <file-path> +
// ["#" + <name> + ["#" + <description> + ["#" + <version>]]] +
- // *1( LWS + ";" + LWS + <mime-type> )
+ // *1( LWS + ";" + LWS + <mime-type-data> )
+ // mime-type-data = <mime-type> + [ LWS + "#" + LWS + <extension> ]
std::vector<std::string> modules = base::SplitString(
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
@@ -105,8 +106,14 @@ void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
if (name_parts.size() > 3)
plugin.version = name_parts[3];
for (size_t j = 1; j < parts.size(); ++j) {
- WebPluginMimeType mime_type(parts[j],
- std::string(),
+ std::vector<std::string> mime_parts = base::SplitString(
+ parts[j], "#", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ DCHECK_GE(mime_parts.size(), 1u);
+ std::string mime_extension;
+ if (mime_parts.size() > 1)
+ mime_extension = mime_parts[1];
+ WebPluginMimeType mime_type(mime_parts[0],
+ mime_extension,
plugin.description);
plugin.mime_types.push_back(mime_type);
}
diff --git a/chromium/content/common/permission_service.mojom b/chromium/content/common/permission_service.mojom
deleted file mode 100644
index 5a6178793c5..00000000000
--- a/chromium/content/common/permission_service.mojom
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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.
-
-module content;
-
-import "content/public/common/permission_status.mojom";
-
-enum PermissionName {
- GEOLOCATION,
- NOTIFICATIONS,
- PUSH_NOTIFICATIONS,
- MIDI,
- MIDI_SYSEX,
- PROTECTED_MEDIA_IDENTIFIER,
- DURABLE_STORAGE,
- AUDIO_CAPTURE,
- VIDEO_CAPTURE,
-};
-
-// The Permission service provides permission handling capabilities by exposing
-// methods to check, request, and revoke permissions. It also allows a client to
-// start listening to permission changes.
-interface PermissionService {
- HasPermission(PermissionName permission, string origin)
- => (PermissionStatus status);
- RequestPermission(PermissionName permission, string origin, bool user_gesture)
- => (PermissionStatus status);
- RequestPermissions(array<PermissionName> permission, string origin, bool user_gesture)
- => (array<PermissionStatus> statuses);
- RevokePermission(PermissionName permission, string origin)
- => (PermissionStatus status);
-
- // Runs the callback next time there is a permission status change for the
- // given { permission, origin }. Callers of this method will have to call it
- // again if they want to keep listening to the changes. To prevent race
- // conditions, the caller must pass the last known value.
- GetNextPermissionChange(PermissionName permission,
- string origin,
- PermissionStatus last_known_status)
- => (PermissionStatus status);
-};
diff --git a/chromium/content/common/platform_notification_messages.h b/chromium/content/common/platform_notification_messages.h
index 8b8d7dad421..5e5d8bb65f7 100644
--- a/chromium/content/common/platform_notification_messages.h
+++ b/chromium/content/common/platform_notification_messages.h
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "content/public/common/notification_resources.h"
#include "content/public/common/platform_notification_data.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h"
@@ -35,9 +36,15 @@ IPC_ENUM_TRAITS_MAX_VALUE(
content::PlatformNotificationData::Direction,
content::PlatformNotificationData::DIRECTION_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(content::PlatformNotificationActionType,
+ content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT)
+
IPC_STRUCT_TRAITS_BEGIN(content::PlatformNotificationAction)
+ IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(action)
IPC_STRUCT_TRAITS_MEMBER(title)
+ IPC_STRUCT_TRAITS_MEMBER(icon)
+ IPC_STRUCT_TRAITS_MEMBER(placeholder)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::PlatformNotificationData)
@@ -47,13 +54,22 @@ IPC_STRUCT_TRAITS_BEGIN(content::PlatformNotificationData)
IPC_STRUCT_TRAITS_MEMBER(body)
IPC_STRUCT_TRAITS_MEMBER(tag)
IPC_STRUCT_TRAITS_MEMBER(icon)
+ IPC_STRUCT_TRAITS_MEMBER(badge)
IPC_STRUCT_TRAITS_MEMBER(vibration_pattern)
+ IPC_STRUCT_TRAITS_MEMBER(timestamp)
+ IPC_STRUCT_TRAITS_MEMBER(renotify)
IPC_STRUCT_TRAITS_MEMBER(silent)
IPC_STRUCT_TRAITS_MEMBER(require_interaction)
IPC_STRUCT_TRAITS_MEMBER(data)
IPC_STRUCT_TRAITS_MEMBER(actions)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(content::NotificationResources)
+ IPC_STRUCT_TRAITS_MEMBER(notification_icon)
+ IPC_STRUCT_TRAITS_MEMBER(badge)
+ IPC_STRUCT_TRAITS_MEMBER(action_icons)
+IPC_STRUCT_TRAITS_END()
+
// Messages sent from the browser to the renderer.
// Informs the renderer that the browser has displayed the notification.
@@ -84,18 +100,20 @@ IPC_MESSAGE_CONTROL2(PlatformNotificationMsg_DidGetNotifications,
// Messages sent from the renderer to the browser.
-IPC_MESSAGE_CONTROL4(PlatformNotificationHostMsg_Show,
- int /* notification_id */,
- GURL /* origin */,
- SkBitmap /* icon */,
- content::PlatformNotificationData /* notification_data */)
-
-IPC_MESSAGE_CONTROL5(PlatformNotificationHostMsg_ShowPersistent,
- int /* request_id */,
- int64_t /* service_worker_registration_id */,
- GURL /* origin */,
- SkBitmap /* icon */,
- content::PlatformNotificationData /* notification_data */)
+IPC_MESSAGE_CONTROL4(
+ PlatformNotificationHostMsg_Show,
+ int /* notification_id */,
+ GURL /* origin */,
+ content::PlatformNotificationData /* notification_data */,
+ content::NotificationResources /* notification_resources */)
+
+IPC_MESSAGE_CONTROL5(
+ PlatformNotificationHostMsg_ShowPersistent,
+ int /* request_id */,
+ int64_t /* service_worker_registration_id */,
+ GURL /* origin */,
+ content::PlatformNotificationData /* notification_data */,
+ content::NotificationResources /* notification_resources */)
IPC_MESSAGE_CONTROL4(PlatformNotificationHostMsg_GetNotifications,
int /* request_id */,
diff --git a/chromium/content/common/plugin_constants_win.cc b/chromium/content/common/plugin_constants_win.cc
deleted file mode 100644
index 026885677e2..00000000000
--- a/chromium/content/common/plugin_constants_win.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2011 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 "content/common/plugin_constants_win.h"
-
-namespace content {
-
-const base::char16 kNativeWindowClassName[] = L"NativeWindowClass";
-const base::char16 kWrapperNativeWindowClassName[] =
- L"WrapperNativeWindowClass";
-const base::char16 kDummyActivationWindowName[] = L"DummyWindowForActivation";
-const base::char16 kPaintMessageName[] = L"Chrome_CustomPaintil";
-const base::char16 kRegistryMozillaPlugins[] = L"SOFTWARE\\MozillaPlugins";
-const base::char16 kMozillaActiveXPlugin[] = L"npmozax.dll";
-const base::char16 kNewWMPPlugin[] = L"np-mswmp.dll";
-const base::char16 kOldWMPPlugin[] = L"npdsplay.dll";
-const base::char16 kYahooApplicationStatePlugin[] = L"npystate.dll";
-const base::char16 kWanWangProtocolHandlerPlugin[] = L"npww.dll";
-const base::char16 kFlashPlugin[] = L"npswf32.dll";
-const base::char16 kAcrobatReaderPlugin[] = L"nppdf32.dll";
-const base::char16 kRealPlayerPlugin[] = L"nppl3260.dll";
-const base::char16 kSilverlightPlugin[] = L"npctrl.dll";
-const base::char16 kJavaPlugin1[] = L"npjp2.dll";
-const base::char16 kJavaPlugin2[] = L"npdeploytk.dll";
-const char kGPUPluginMimeType[] = "application/vnd.google.chrome.gpu-plugin";
-const base::char16 kPluginDummyParentProperty[] = L"NPAPIPluginDummyParent";
-
-} // namespace content
diff --git a/chromium/content/common/plugin_constants_win.h b/chromium/content/common/plugin_constants_win.h
deleted file mode 100644
index 2269592d5ae..00000000000
--- a/chromium/content/common/plugin_constants_win.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2011 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 CONTENT_COMMON_PLUGIN_CONSTANTS_WIN_H_
-#define CONTENT_COMMON_PLUGIN_CONSTANTS_WIN_H_
-
-#include "base/strings/string16.h"
-#include "build/build_config.h"
-
-#if !defined(OS_WIN)
-#error "Windows-only header"
-#endif
-
-namespace content {
-
-// The window class name for a plugin window.
-extern const base::char16 kNativeWindowClassName[];
-
-// The name of the window class name for the wrapper HWND around the actual
-// plugin window that's used when running in multi-process mode. This window
-// is created on the browser UI thread.
-extern const base::char16 kWrapperNativeWindowClassName[];
-
-extern const base::char16 kDummyActivationWindowName[];
-
-// The name of the custom window message that the browser uses to tell the
-// plugin process to paint a window.
-extern const base::char16 kPaintMessageName[];
-
-// The name of the registry key which NPAPI plugins update on installation.
-extern const base::char16 kRegistryMozillaPlugins[];
-
-extern const base::char16 kMozillaActiveXPlugin[];
-extern const base::char16 kNewWMPPlugin[];
-extern const base::char16 kOldWMPPlugin[];
-extern const base::char16 kYahooApplicationStatePlugin[];
-extern const base::char16 kWanWangProtocolHandlerPlugin[];
-extern const base::char16 kFlashPlugin[];
-extern const base::char16 kAcrobatReaderPlugin[];
-extern const base::char16 kRealPlayerPlugin[];
-extern const base::char16 kSilverlightPlugin[];
-extern const base::char16 kJavaPlugin1[];
-extern const base::char16 kJavaPlugin2[];
-
-extern const char kGPUPluginMimeType[];
-
-extern const base::char16 kPluginDummyParentProperty[];
-
-} // namespace content
-
-#endif // CONTENT_COMMON_PLUGIN_CONSTANTS_WIN_H_
diff --git a/chromium/content/common/plugin_list.cc b/chromium/content/common/plugin_list.cc
index 80438818181..eff0f66b269 100644
--- a/chromium/content/common/plugin_list.cc
+++ b/chromium/content/common/plugin_list.cc
@@ -20,10 +20,6 @@
#include "net/base/mime_util.h"
#include "url/gurl.h"
-#if defined(OS_WIN)
-#include "content/common/plugin_constants_win.h"
-#endif
-
namespace content {
namespace {
@@ -37,42 +33,11 @@ PluginList* PluginList::Singleton() {
return g_singleton.Pointer();
}
-// static
-bool PluginList::DebugPluginLoading() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDebugPluginLoading);
-}
-
-void PluginList::DisablePluginsDiscovery() {
- plugins_discovery_disabled_ = true;
-}
-
void PluginList::RefreshPlugins() {
base::AutoLock lock(lock_);
loading_state_ = LOADING_STATE_NEEDS_REFRESH;
}
-void PluginList::AddExtraPluginPath(const base::FilePath& plugin_path) {
- // Chrome OS only loads plugins from /opt/google/chrome/plugins.
-#if !defined(OS_CHROMEOS)
- base::AutoLock lock(lock_);
- extra_plugin_paths_.push_back(plugin_path);
-#endif
-}
-
-void PluginList::RemoveExtraPluginPath(const base::FilePath& plugin_path) {
- base::AutoLock lock(lock_);
- RemoveExtraPluginPathLocked(plugin_path);
-}
-
-void PluginList::AddExtraPluginDir(const base::FilePath& plugin_dir) {
- // Chrome OS only loads plugins from /opt/google/chrome/plugins.
-#if !defined(OS_CHROMEOS)
- base::AutoLock lock(lock_);
- extra_plugin_dirs_.push_back(plugin_dir);
-#endif
-}
-
void PluginList::RegisterInternalPlugin(const WebPluginInfo& info,
bool add_at_beginning) {
base::AutoLock lock(lock_);
@@ -114,70 +79,18 @@ void PluginList::GetInternalPlugins(
bool PluginList::ReadPluginInfo(const base::FilePath& filename,
WebPluginInfo* info) {
- {
- base::AutoLock lock(lock_);
- for (size_t i = 0; i < internal_plugins_.size(); ++i) {
- if (filename == internal_plugins_[i].path) {
- *info = internal_plugins_[i];
- return true;
- }
- }
- }
-
- return PluginList::ReadWebPluginInfo(filename, info);
-}
-
-// static
-bool PluginList::ParseMimeTypes(
- const std::string& mime_types_str,
- const std::string& file_extensions_str,
- const base::string16& mime_type_descriptions_str,
- std::vector<WebPluginMimeType>* parsed_mime_types) {
- std::vector<std::string> mime_types = base::SplitString(
- mime_types_str, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<std::string> file_extensions = base::SplitString(
- file_extensions_str, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<base::string16> descriptions = base::SplitString(
- mime_type_descriptions_str, base::string16(1, '|'), base::TRIM_WHITESPACE,
- base::SPLIT_WANT_ALL);
-
- parsed_mime_types->clear();
-
- if (mime_types.empty())
- return false;
-
- for (size_t i = 0; i < mime_types.size(); ++i) {
- WebPluginMimeType mime_type;
- mime_type.mime_type = base::ToLowerASCII(mime_types[i]);
- if (file_extensions.size() > i) {
- mime_type.file_extensions = base::SplitString(
- file_extensions[i], ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- }
-
- if (descriptions.size() > i) {
- mime_type.description = descriptions[i];
-
- // On Windows, the description likely has a list of file extensions
- // embedded in it (e.g. "SurfWriter file (*.swr)"). Remove an extension
- // list from the description if it is present.
- size_t ext = mime_type.description.find(base::ASCIIToUTF16("(*"));
- if (ext != base::string16::npos) {
- if (ext > 1 && mime_type.description[ext - 1] == ' ')
- ext--;
-
- mime_type.description.erase(ext);
- }
+ base::AutoLock lock(lock_);
+ for (const auto& plugin : internal_plugins_) {
+ if (filename == plugin.path) {
+ *info = plugin;
+ return true;
}
-
- parsed_mime_types->push_back(mime_type);
}
-
- return true;
+ return false;
}
PluginList::PluginList()
- : loading_state_(LOADING_STATE_NEEDS_REFRESH),
- plugins_discovery_disabled_(false) {
+ : loading_state_(LOADING_STATE_NEEDS_REFRESH) {
}
bool PluginList::PrepareForPluginLoading() {
@@ -189,7 +102,7 @@ bool PluginList::PrepareForPluginLoading() {
return true;
}
-void PluginList::LoadPlugins(bool include_npapi) {
+void PluginList::LoadPlugins() {
if (!PrepareForPluginLoading())
return;
@@ -203,7 +116,7 @@ void PluginList::LoadPlugins(bool include_npapi) {
will_load_callback.Run();
std::vector<base::FilePath> plugin_paths;
- GetPluginPathsToLoad(&plugin_paths, include_npapi);
+ GetPluginPathsToLoad(&plugin_paths);
for (std::vector<base::FilePath>::const_iterator it = plugin_paths.begin();
it != plugin_paths.end();
@@ -219,41 +132,30 @@ bool PluginList::LoadPluginIntoPluginList(
const base::FilePath& path,
std::vector<WebPluginInfo>* plugins,
WebPluginInfo* plugin_info) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Loading plugin " << path.value();
if (!ReadPluginInfo(path, plugin_info))
return false;
- if (!ShouldLoadPluginUsingPluginList(*plugin_info, plugins))
- return false;
-
-#if defined(OS_WIN) && !defined(NDEBUG)
- if (path.BaseName().value() != L"npspy.dll") // Make an exception for NPSPY
-#endif
- {
- for (size_t i = 0; i < plugin_info->mime_types.size(); ++i) {
- // TODO: don't load global handlers for now.
- // WebKit hands to the Plugin before it tries
- // to handle mimeTypes on its own.
- const std::string &mime_type = plugin_info->mime_types[i].mime_type;
- if (mime_type == "*")
- return false;
- }
+ // TODO(piman): Do we still need this after NPAPI removal?
+ for (size_t i = 0; i < plugin_info->mime_types.size(); ++i) {
+ // TODO: don't load global handlers for now.
+ // WebKit hands to the Plugin before it tries
+ // to handle mimeTypes on its own.
+ const std::string &mime_type = plugin_info->mime_types[i].mime_type;
+ if (mime_type == "*")
+ return false;
}
plugins->push_back(*plugin_info);
return true;
}
-void PluginList::GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths,
- bool include_npapi) {
+void PluginList::GetPluginPathsToLoad(
+ std::vector<base::FilePath>* plugin_paths) {
// Don't want to hold the lock while loading new plugins, so we don't block
// other methods if they're called on other threads.
std::vector<base::FilePath> extra_plugin_paths;
- std::vector<base::FilePath> extra_plugin_dirs;
{
base::AutoLock lock(lock_);
extra_plugin_paths = extra_plugin_paths_;
- extra_plugin_dirs = extra_plugin_dirs_;
}
for (size_t i = 0; i < extra_plugin_paths.size(); ++i) {
@@ -264,22 +166,6 @@ void PluginList::GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths,
}
plugin_paths->push_back(path);
}
-
- if (include_npapi) {
- // A bit confusingly, this function is used to load Pepper plugins as well.
- // Those are all internal plugins so we have to use extra_plugin_paths.
- for (size_t i = 0; i < extra_plugin_dirs.size(); ++i)
- GetPluginsInDir(extra_plugin_dirs[i], plugin_paths);
-
- std::vector<base::FilePath> directories_to_scan;
- GetPluginDirectories(&directories_to_scan);
- for (size_t i = 0; i < directories_to_scan.size(); ++i)
- GetPluginsInDir(directories_to_scan[i], plugin_paths);
-
-#if defined(OS_WIN)
- GetPluginPathsFromRegistry(plugin_paths);
-#endif
- }
}
void PluginList::SetPlugins(const std::vector<WebPluginInfo>& plugins) {
@@ -298,9 +184,8 @@ void PluginList::set_will_load_plugins_callback(const base::Closure& callback) {
will_load_plugins_callback_ = callback;
}
-void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins,
- bool include_npapi) {
- LoadPlugins(include_npapi);
+void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) {
+ LoadPlugins();
base::AutoLock lock(lock_);
plugins->insert(plugins->end(), plugins_list_.begin(), plugins_list_.end());
}
@@ -317,14 +202,13 @@ void PluginList::GetPluginInfoArray(
const std::string& mime_type,
bool allow_wildcard,
bool* use_stale,
- bool include_npapi,
std::vector<WebPluginInfo>* info,
std::vector<std::string>* actual_mime_types) {
DCHECK(mime_type == base::ToLowerASCII(mime_type));
DCHECK(info);
if (!use_stale)
- LoadPlugins(include_npapi);
+ LoadPlugins();
base::AutoLock lock(lock_);
if (use_stale)
*use_stale = (loading_state_ != LOADING_STATE_UP_TO_DATE);
diff --git a/chromium/content/common/plugin_list.h b/chromium/content/common/plugin_list.h
index 0b31ab0d7e1..b18b061043b 100644
--- a/chromium/content/common/plugin_list.h
+++ b/chromium/content/common/plugin_list.h
@@ -40,35 +40,16 @@ class CONTENT_EXPORT PluginList {
// Gets the one instance of the PluginList.
static PluginList* Singleton();
- // Returns true if we're in debug-plugin-loading mode. This is controlled
- // by a command line switch.
- static bool DebugPluginLoading();
-
// Returns true if the plugin supports |mime_type|. |mime_type| should be all
// lower case.
static bool SupportsType(const WebPluginInfo& plugin,
const std::string& mime_type,
bool allow_wildcard);
- // Disables discovery of third_party plugins in standard places next time
- // plugins are loaded.
- void DisablePluginsDiscovery();
-
// Cause the plugin list to refresh next time they are accessed, regardless
// of whether they are already loaded.
void RefreshPlugins();
- // Add/Remove an extra plugin to load when we actually do the loading. Must
- // be called before the plugins have been loaded.
- void AddExtraPluginPath(const base::FilePath& plugin_path);
- void RemoveExtraPluginPath(const base::FilePath& plugin_path);
-
- // Same as above, but specifies a directory in which to search for plugins.
- void AddExtraPluginDir(const base::FilePath& plugin_dir);
-
- // Get the ordered list of directories from which to load plugins
- void GetPluginDirectories(std::vector<base::FilePath>* plugin_dirs);
-
// Register an internal plugin with the specified plugin information.
// An internal plugin must be registered before it can
// be loaded using PluginList::LoadPlugin().
@@ -90,19 +71,8 @@ class CONTENT_EXPORT PluginList {
bool ReadPluginInfo(const base::FilePath& filename,
WebPluginInfo* info);
- // In Windows plugins, the mime types are passed as a specially formatted list
- // of strings. This function parses those strings into a WebPluginMimeType
- // vector.
- // TODO(evan): move this code into plugin_list_win.
- static bool ParseMimeTypes(
- const std::string& mime_types,
- const std::string& file_extensions,
- const base::string16& mime_type_descriptions,
- std::vector<WebPluginMimeType>* parsed_mime_types);
-
// Get all the plugins synchronously, loading them if necessary.
- void GetPlugins(std::vector<WebPluginInfo>* plugins,
- bool include_npapi);
+ void GetPlugins(std::vector<WebPluginInfo>* plugins);
// Copies the list of plugins into |plugins| without loading them.
// Returns true if the list of plugins is up-to-date.
@@ -124,7 +94,6 @@ class CONTENT_EXPORT PluginList {
const std::string& mime_type,
bool allow_wildcard,
bool* use_stale,
- bool include_npapi,
std::vector<WebPluginInfo>* info,
std::vector<std::string>* actual_mime_types);
@@ -138,8 +107,7 @@ class CONTENT_EXPORT PluginList {
// using a different instance of this class.
// Computes a list of all plugins to potentially load from all sources.
- void GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths,
- bool include_npapi);
+ void GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths);
// Signals that plugin loading will start. This method should be called before
// loading plugins with a different instance of this class. Returns false if
@@ -155,12 +123,6 @@ class CONTENT_EXPORT PluginList {
virtual ~PluginList();
- // Creates a WebPluginInfo structure given a plugin's path. On success
- // returns true, with the information being put into "info".
- // Returns false if the library couldn't be found, or if it's not a plugin.
- static bool ReadWebPluginInfo(const base::FilePath& filename,
- WebPluginInfo* info);
-
private:
enum LoadingState {
LOADING_STATE_NEEDS_REFRESH,
@@ -174,18 +136,7 @@ class CONTENT_EXPORT PluginList {
PluginList();
// Load all plugins from the default plugins directory.
- void LoadPlugins(bool include_npapi);
-
- // Walks a directory and produces a list of all the plugins to potentially
- // load in that directory.
- void GetPluginsInDir(const base::FilePath& path,
- std::vector<base::FilePath>* plugins);
-
- // Returns true if we should load the given plugin, or false otherwise.
- // |plugins| is the list of plugins we have crawled in the current plugin
- // loading run.
- bool ShouldLoadPluginUsingPluginList(const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins);
+ void LoadPlugins();
// Returns true if the given plugin supports a given file extension.
// |extension| should be all lower case. If |mime_type| is not NULL, it will
@@ -200,16 +151,6 @@ class CONTENT_EXPORT PluginList {
void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path);
//
- // Command-line switches
- //
-
-#if defined(OS_WIN)
- // Gets plugin paths registered under HKCU\Software\MozillaPlugins and
- // HKLM\Software\MozillaPlugins.
- void GetPluginPathsFromRegistry(std::vector<base::FilePath>* plugins);
-#endif
-
- //
// Internals
//
@@ -221,9 +162,6 @@ class CONTENT_EXPORT PluginList {
// Extra plugin paths that we want to search when loading.
std::vector<base::FilePath> extra_plugin_paths_;
- // Extra plugin directories that we want to search when loading.
- std::vector<base::FilePath> extra_plugin_dirs_;
-
// Holds information about internal plugins.
std::vector<WebPluginInfo> internal_plugins_;
@@ -237,10 +175,6 @@ class CONTENT_EXPORT PluginList {
// accessed on multiple threads.
base::Lock lock_;
- // Flag indicating whether third_party plugins will be searched for
- // in common places.
- bool plugins_discovery_disabled_;
-
DISALLOW_COPY_AND_ASSIGN(PluginList);
};
diff --git a/chromium/content/common/plugin_list_mac.mm b/chromium/content/common/plugin_list_mac.mm
deleted file mode 100644
index b3d726c0d70..00000000000
--- a/chromium/content/common/plugin_list_mac.mm
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 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 "content/common/plugin_list.h"
-
-#import <Carbon/Carbon.h>
-#import <Foundation/Foundation.h>
-
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/native_library.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-
-using base::ScopedCFTypeRef;
-
-namespace content {
-
-namespace {
-
-void GetPluginCommonDirectory(std::vector<base::FilePath>* plugin_dirs,
- bool user) {
- // Note that there are no NSSearchPathDirectory constants for these
- // directories so we can't use Cocoa's NSSearchPathForDirectoriesInDomains().
- // Interestingly, Safari hard-codes the location (see
- // WebKit/WebKit/mac/Plugins/WebPluginDatabase.mm's +_defaultPlugInPaths).
- FSRef ref;
- OSErr err = FSFindFolder(user ? kUserDomain : kLocalDomain,
- kInternetPlugInFolderType, false, &ref);
-
- if (err)
- return;
-
- plugin_dirs->push_back(base::FilePath(base::mac::PathFromFSRef(ref)));
-}
-
-// Returns true if the plugin should be prevented from loading.
-bool IsBlacklistedPlugin(const WebPluginInfo& info) {
- // We blacklist Gears by included MIME type, since that is more stable than
- // its name. Be careful about adding any more plugins to this list though,
- // since it's easy to accidentally blacklist plugins that support lots of
- // MIME types.
- for (const WebPluginMimeType& mime : info.mime_types) {
- // The Gears plugin is Safari-specific, so don't load it.
- if (mime.mime_type == "application/x-googlegears")
- return true;
- }
-
- // Versions of Flip4Mac 2.3 before 2.3.6 often hang the renderer, so don't
- // load them.
- if (base::StartsWith(info.name,
- base::ASCIIToUTF16("Flip4Mac Windows Media"),
- base::CompareCase::INSENSITIVE_ASCII) &&
- base::StartsWith(info.version, base::ASCIIToUTF16("2.3"),
- base::CompareCase::SENSITIVE)) {
- std::vector<base::StringPiece16> components = base::SplitStringPiece(
- info.version, base::ASCIIToUTF16("."), base::TRIM_WHITESPACE,
- base::SPLIT_WANT_ALL);
- int bugfix_version = 0;
- return (components.size() >= 3 &&
- base::StringToInt(components[2], &bugfix_version) &&
- bugfix_version < 6);
- }
-
- return false;
-}
-
-NSDictionary* GetMIMETypes(CFBundleRef bundle) {
- NSString* mime_filename =
- (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
- CFSTR("WebPluginMIMETypesFilename"));
-
- if (mime_filename) {
-
- // get the file
-
- NSString* mime_path =
- [NSString stringWithFormat:@"%@/Library/Preferences/%@",
- NSHomeDirectory(), mime_filename];
- NSDictionary* mime_file_dict =
- [NSDictionary dictionaryWithContentsOfFile:mime_path];
-
- // is it valid?
-
- bool valid_file = false;
- if (mime_file_dict) {
- NSString* l10n_name =
- [mime_file_dict objectForKey:@"WebPluginLocalizationName"];
- NSString* preferred_l10n = [[NSLocale currentLocale] localeIdentifier];
- if ([l10n_name isEqualToString:preferred_l10n])
- valid_file = true;
- }
-
- if (valid_file)
- return [mime_file_dict objectForKey:@"WebPluginMIMETypes"];
-
- // dammit, I didn't want to have to do this
-
- typedef void (*CreateMIMETypesPrefsPtr)(void);
- CreateMIMETypesPrefsPtr create_prefs_file =
- (CreateMIMETypesPrefsPtr)CFBundleGetFunctionPointerForName(
- bundle, CFSTR("BP_CreatePluginMIMETypesPreferences"));
- if (!create_prefs_file)
- return nil;
- create_prefs_file();
-
- // one more time
-
- mime_file_dict = [NSDictionary dictionaryWithContentsOfFile:mime_path];
- if (mime_file_dict)
- return [mime_file_dict objectForKey:@"WebPluginMIMETypes"];
- else
- return nil;
-
- } else {
- return (NSDictionary*)CFBundleGetValueForInfoDictionaryKey(bundle,
- CFSTR("WebPluginMIMETypes"));
- }
-}
-
-bool ReadPlistPluginInfo(const base::FilePath& filename, CFBundleRef bundle,
- WebPluginInfo* info) {
- NSDictionary* mime_types = GetMIMETypes(bundle);
- if (!mime_types)
- return false; // no type info here; try elsewhere
-
- for (NSString* mime_type in [mime_types allKeys]) {
- NSDictionary* mime_dict = [mime_types objectForKey:mime_type];
- NSNumber* type_enabled = [mime_dict objectForKey:@"WebPluginTypeEnabled"];
- NSString* mime_desc = [mime_dict objectForKey:@"WebPluginTypeDescription"];
- NSArray* mime_exts = [mime_dict objectForKey:@"WebPluginExtensions"];
-
- // Skip any disabled types.
- if (type_enabled && ![type_enabled boolValue])
- continue;
-
- WebPluginMimeType mime;
- mime.mime_type = base::SysNSStringToUTF8([mime_type lowercaseString]);
- // Remove PDF from the list of types handled by QuickTime, since it provides
- // a worse experience than just downloading the PDF.
- if (mime.mime_type == "application/pdf" &&
- base::StartsWith(filename.BaseName().value(), "QuickTime",
- base::CompareCase::INSENSITIVE_ASCII)) {
- continue;
- }
-
- if (mime_desc)
- mime.description = base::SysNSStringToUTF16(mime_desc);
- for (NSString* ext in mime_exts)
- mime.file_extensions.push_back(
- base::SysNSStringToUTF8([ext lowercaseString]));
-
- info->mime_types.push_back(mime);
- }
-
- NSString* plugin_name =
- (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
- CFSTR("WebPluginName"));
- NSString* plugin_vers =
- (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
- CFSTR("CFBundleShortVersionString"));
- NSString* plugin_desc =
- (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
- CFSTR("WebPluginDescription"));
-
- if (plugin_name)
- info->name = base::SysNSStringToUTF16(plugin_name);
- else
- info->name = base::UTF8ToUTF16(filename.BaseName().value());
- info->path = filename;
- if (plugin_vers)
- info->version = base::SysNSStringToUTF16(plugin_vers);
- if (plugin_desc)
- info->desc = base::SysNSStringToUTF16(plugin_desc);
- else
- info->desc = base::UTF8ToUTF16(filename.BaseName().value());
-
- return true;
-}
-
-} // namespace
-
-bool PluginList::ReadWebPluginInfo(const base::FilePath &filename,
- WebPluginInfo* info) {
- // There are three ways to get information about plugin capabilities:
- // 1) a set of Info.plist keys, documented at
- // http://developer.apple.com/documentation/InternetWeb/Conceptual/WebKit_PluginProgTopic/Concepts/AboutPlugins.html .
- // 2) a set of STR# resources, documented at
- // https://developer.mozilla.org/En/Gecko_Plugin_API_Reference/Plug-in_Development_Overview .
- // 3) a NP_GetMIMEDescription() entry point, documented at
- // https://developer.mozilla.org/en/NP_GetMIMEDescription
- //
- // Mozilla supported (3), but WebKit never has, so no plugins rely on it. Most
- // browsers supported (2) and then added support for (1); Chromium originally
- // supported (2) and (1), but now supports only (1) as (2) is deprecated.
- //
- // For the Info.plist version, the data is formatted as follows (in text plist
- // format):
- // {
- // ... the usual plist keys ...
- // WebPluginDescription = <<plugindescription>>;
- // WebPluginMIMETypes = {
- // <<type0mimetype>> = {
- // WebPluginExtensions = (
- // <<type0fileextension0>>,
- // ...
- // <<type0fileextensionk>>,
- // );
- // WebPluginTypeDescription = <<type0description>>;
- // };
- // <<type1mimetype>> = { ... };
- // ...
- // <<typenmimetype>> = { ... };
- // };
- // WebPluginName = <<pluginname>>;
- // }
- //
- // Alternatively (and this is undocumented), rather than a WebPluginMIMETypes
- // key, there may be a WebPluginMIMETypesFilename key. If it is present, then
- // it is the name of a file in the user's preferences folder in which to find
- // the WebPluginMIMETypes key. If the key is present but the file doesn't
- // exist, we must load the plugin and call a specific function to have the
- // plugin create the file.
-
- ScopedCFTypeRef<CFURLRef> bundle_url(CFURLCreateFromFileSystemRepresentation(
- kCFAllocatorDefault, (const UInt8*)filename.value().c_str(),
- filename.value().length(), true));
- if (!bundle_url) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::ReadWebPluginInfo could not create bundle URL";
- return false;
- }
- ScopedCFTypeRef<CFBundleRef> bundle(CFBundleCreate(kCFAllocatorDefault,
- bundle_url.get()));
- if (!bundle) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::ReadWebPluginInfo could not create CFBundleRef";
- return false;
- }
-
- // preflight
-
- OSType type = 0;
- CFBundleGetPackageInfo(bundle.get(), &type, NULL);
- if (type != FOUR_CHAR_CODE('BRPL')) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::ReadWebPluginInfo bundle is not BRPL, is " << type;
- return false;
- }
-
- CFErrorRef error;
- Boolean would_load = CFBundlePreflightExecutable(bundle.get(), &error);
- if (!would_load) {
- ScopedCFTypeRef<CFStringRef> error_string(CFErrorCopyDescription(error));
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "PluginLib::ReadWebPluginInfo bundle failed preflight: "
- << base::SysCFStringRefToUTF8(error_string);
- return false;
- }
-
- // get the info
-
- if (ReadPlistPluginInfo(filename, bundle.get(), info))
- return true;
-
- // ... or not
-
- return false;
-}
-
-void PluginList::GetPluginDirectories(
- std::vector<base::FilePath>* plugin_dirs) {
- if (PluginList::plugins_discovery_disabled_)
- return;
-
- // Load from the user's area
- GetPluginCommonDirectory(plugin_dirs, true);
-
- // Load from the machine-wide area
- GetPluginCommonDirectory(plugin_dirs, false);
-}
-
-void PluginList::GetPluginsInDir(
- const base::FilePath& path, std::vector<base::FilePath>* plugins) {
- base::FileEnumerator enumerator(path,
- false, // not recursive
- base::FileEnumerator::DIRECTORIES);
- for (base::FilePath path = enumerator.Next(); !path.value().empty();
- path = enumerator.Next()) {
- plugins->push_back(path);
- }
-}
-
-bool PluginList::ShouldLoadPluginUsingPluginList(
- const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
- return !IsBlacklistedPlugin(info);
-}
-
-} // namespace content
diff --git a/chromium/content/common/plugin_list_posix.cc b/chromium/content/common/plugin_list_posix.cc
deleted file mode 100644
index 122fd59be42..00000000000
--- a/chromium/content/common/plugin_list_posix.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2011 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 "content/common/plugin_list.h"
-
-namespace content {
-
-bool PluginList::ReadWebPluginInfo(const base::FilePath& filename,
- WebPluginInfo* info) {
- return false;
-}
-
-void PluginList::GetPluginDirectories(
- std::vector<base::FilePath>* plugin_dirs) {
-}
-
-void PluginList::GetPluginsInDir(const base::FilePath& dir_path,
- std::vector<base::FilePath>* plugins) {
-}
-
-bool PluginList::ShouldLoadPluginUsingPluginList(
- const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Considering " << info.path.value() << " (" << info.name << ")";
-
- if (info.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) {
- NOTREACHED() << "NPAPI plugins are not supported";
- return false;
- }
-
- VLOG_IF(1, PluginList::DebugPluginLoading()) << "Using " << info.path.value();
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/common/plugin_list_unittest.cc b/chromium/content/common/plugin_list_unittest.cc
index 4b8150b499b..d28c0eb589b 100644
--- a/chromium/content/common/plugin_list_unittest.cc
+++ b/chromium/content/common/plugin_list_unittest.cc
@@ -52,7 +52,6 @@ class PluginListTest : public testing::Test {
}
void SetUp() override {
- plugin_list_.DisablePluginsDiscovery();
plugin_list_.RegisterInternalPlugin(bar_plugin_, false);
foo_plugin_.mime_types.push_back(
WebPluginMimeType(kFooMimeType, kFooFileType, std::string()));
@@ -67,7 +66,7 @@ class PluginListTest : public testing::Test {
TEST_F(PluginListTest, GetPlugins) {
std::vector<WebPluginInfo> plugins;
- plugin_list_.GetPlugins(&plugins, true);
+ plugin_list_.GetPlugins(&plugins);
EXPECT_EQ(2u, plugins.size());
EXPECT_TRUE(Contains(plugins, foo_plugin_));
EXPECT_TRUE(Contains(plugins, bar_plugin_));
@@ -82,7 +81,7 @@ TEST_F(PluginListTest, BadPluginDescription) {
// Now we should have them in the state we specified above.
plugin_list_.RefreshPlugins();
std::vector<WebPluginInfo> plugins;
- plugin_list_.GetPlugins(&plugins, true);
+ plugin_list_.GetPlugins(&plugins);
ASSERT_TRUE(Contains(plugins, plugin_3043));
}
@@ -99,7 +98,6 @@ TEST_F(PluginListTest, GetPluginInfoArray) {
"application/octet-stream",
false, // allow_wildcard
NULL, // use_stale
- false, // include_npapi
&plugins,
&actual_mime_types);
EXPECT_EQ(0u, plugins.size());
@@ -112,7 +110,6 @@ TEST_F(PluginListTest, GetPluginInfoArray) {
kFooMimeType,
false, // allow_wildcard
NULL, // use_stale
- false, // include_npapi
&plugins,
&actual_mime_types);
EXPECT_EQ(1u, plugins.size());
@@ -127,7 +124,6 @@ TEST_F(PluginListTest, GetPluginInfoArray) {
"",
false, // allow_wildcard
NULL, // use_stale
- false, // include_npapi
&plugins,
&actual_mime_types);
EXPECT_EQ(1u, plugins.size());
diff --git a/chromium/content/common/plugin_list_win.cc b/chromium/content/common/plugin_list_win.cc
deleted file mode 100644
index e96cc05698a..00000000000
--- a/chromium/content/common/plugin_list_win.cc
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright (c) 2012 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 "content/common/plugin_list.h"
-
-#include <stddef.h>
-
-#include <set>
-
-#include "base/file_version_info.h"
-#include "base/file_version_info_win.h"
-#include "base/files/file_util.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/path_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/pe_image.h"
-#include "base/win/registry.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/windows_version.h"
-#include "build/build_config.h"
-#include "content/common/plugin_constants_win.h"
-
-namespace content {
-namespace {
-
-const base::char16 kRegistryApps[] =
- L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
-const base::char16 kRegistryAcrobat[] = L"Acrobat.exe";
-const base::char16 kRegistryAcrobatReader[] = L"AcroRd32.exe";
-const base::char16 kRegistryWindowsMedia[] = L"wmplayer.exe";
-const base::char16 kRegistryQuickTime[] = L"QuickTimePlayer.exe";
-const base::char16 kRegistryPath[] = L"Path";
-const base::char16 kRegistryFirefoxInstalled[] =
- L"SOFTWARE\\Mozilla\\Mozilla Firefox";
-const base::char16 kRegistryJava[] =
- L"Software\\JavaSoft\\Java Runtime Environment";
-const base::char16 kRegistryBrowserJavaVersion[] = L"BrowserJavaVersion";
-const base::char16 kRegistryCurrentJavaVersion[] = L"CurrentVersion";
-const base::char16 kRegistryJavaHome[] = L"JavaHome";
-const base::char16 kJavaDeploy1[] = L"npdeploytk.dll";
-const base::char16 kJavaDeploy2[] = L"npdeployjava1.dll";
-
-base::FilePath AppendPluginsDir(const base::FilePath& path) {
- return path.AppendASCII("plugins");
-}
-
-// Gets the directory where the application data and libraries exist. This
-// may be a versioned subdirectory, or it may be the same directory as the
-// GetExeDirectory(), depending on the embedder's implementation.
-// Path is an output parameter to receive the path.
-void GetAppDirectory(std::set<base::FilePath>* plugin_dirs) {
- base::FilePath app_path;
- if (!PathService::Get(base::DIR_MODULE, &app_path))
- return;
- plugin_dirs->insert(AppendPluginsDir(app_path));
-}
-
-// Gets the directory where the launching executable resides on disk.
-// Path is an output parameter to receive the path.
-void GetExeDirectory(std::set<base::FilePath>* plugin_dirs) {
- base::FilePath exe_path;
- if (!PathService::Get(base::DIR_EXE, &exe_path))
- return;
- plugin_dirs->insert(AppendPluginsDir(exe_path));
-}
-
-// Gets the installed path for a registered app.
-bool GetInstalledPath(const base::char16* app, base::FilePath* out) {
- base::string16 reg_path(kRegistryApps);
- reg_path.append(L"\\");
- reg_path.append(app);
-
- base::win::RegKey hkcu_key(HKEY_CURRENT_USER, reg_path.c_str(), KEY_READ);
- base::string16 path;
- // As of Win7 AppPaths can also be registered in HKCU: http://goo.gl/UgFOf.
- if (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
- hkcu_key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS) {
- *out = base::FilePath(path);
- return true;
- } else {
- base::win::RegKey hklm_key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ);
- if (hklm_key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS) {
- *out = base::FilePath(path);
- return true;
- }
- }
-
- return false;
-}
-
-// Search the registry at the given path and detect plugin directories.
-void GetPluginsInRegistryDirectory(HKEY root_key,
- const base::string16& registry_folder,
- REGSAM wow64_access,
- std::set<base::FilePath>* plugin_dirs) {
- for (base::win::RegistryKeyIterator iter(
- root_key, registry_folder.c_str(), wow64_access);
- iter.Valid();
- ++iter) {
- // Use the registry to gather plugin across the file system.
- base::string16 reg_path = registry_folder;
- reg_path.append(L"\\");
- reg_path.append(iter.Name());
- base::win::RegKey key(root_key, reg_path.c_str(), KEY_READ | wow64_access);
-
- base::string16 path;
- if (key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS)
- plugin_dirs->insert(base::FilePath(path));
- }
-}
-
-// Enumerate through the registry key to find all installed FireFox paths.
-// FireFox 3 beta and version 2 can coexist. See bug: 1025003
-void GetFirefoxInstalledPaths(std::vector<base::FilePath>* out) {
- base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE,
- kRegistryFirefoxInstalled,
- KEY_WOW64_32KEY);
- for (; it.Valid(); ++it) {
- base::string16 full_path = base::string16(kRegistryFirefoxInstalled) +
- L"\\" + it.Name() + L"\\Main";
- base::win::RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
- base::string16 install_dir;
- if (key.ReadValue(L"Install Directory", &install_dir) != ERROR_SUCCESS)
- continue;
- out->push_back(base::FilePath(install_dir));
- }
-}
-
-// Get plugin directory locations from the Firefox install path. This is kind
-// of a kludge, but it helps us locate the flash player for users that
-// already have it for firefox. Not having to download yet-another-plugin
-// is a good thing.
-void GetFirefoxDirectory(std::set<base::FilePath>* plugin_dirs) {
- std::vector<base::FilePath> paths;
- GetFirefoxInstalledPaths(&paths);
- for (unsigned int i = 0; i < paths.size(); ++i) {
- plugin_dirs->insert(AppendPluginsDir(paths[i]));
- }
-
- base::FilePath firefox_app_data_plugin_path;
- if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
- firefox_app_data_plugin_path =
- firefox_app_data_plugin_path.AppendASCII("Mozilla");
- plugin_dirs->insert(AppendPluginsDir(firefox_app_data_plugin_path));
- }
-}
-
-// Hardcoded logic to detect Acrobat plugins locations.
-void GetAcrobatDirectory(std::set<base::FilePath>* plugin_dirs) {
- base::FilePath path;
- if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
- !GetInstalledPath(kRegistryAcrobat, &path)) {
- return;
- }
-
- plugin_dirs->insert(path.Append(L"Browser"));
-}
-
-// Hardcoded logic to detect QuickTime plugin location.
-void GetQuicktimeDirectory(std::set<base::FilePath>* plugin_dirs) {
- base::FilePath path;
- if (GetInstalledPath(kRegistryQuickTime, &path))
- plugin_dirs->insert(AppendPluginsDir(path));
-}
-
-// Hardcoded logic to detect Windows Media Player plugin location.
-void GetWindowsMediaDirectory(std::set<base::FilePath>* plugin_dirs) {
- base::FilePath path;
- if (GetInstalledPath(kRegistryWindowsMedia, &path))
- plugin_dirs->insert(path);
-}
-
-// Hardcoded logic to detect Java plugin location.
-void GetJavaDirectory(std::set<base::FilePath>* plugin_dirs) {
- // Load the new NPAPI Java plugin
- // 1. Open the main JRE key under HKLM
- base::win::RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava,
- KEY_QUERY_VALUE);
-
- // 2. Read the current Java version
- base::string16 java_version;
- if (java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version) !=
- ERROR_SUCCESS) {
- java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);
- }
-
- if (!java_version.empty()) {
- java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);
-
- // 3. Install path of the JRE binaries is specified in "JavaHome"
- // value under the Java version key.
- base::string16 java_plugin_directory;
- if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory) ==
- ERROR_SUCCESS) {
- // 4. The new plugin resides under the 'bin/new_plugin'
- // subdirectory.
- DCHECK(!java_plugin_directory.empty());
- java_plugin_directory.append(L"\\bin\\new_plugin");
-
- // 5. We don't know the exact name of the DLL but it's in the form
- // NP*.dll so just invoke LoadPlugins on this path.
- plugin_dirs->insert(base::FilePath(java_plugin_directory));
- }
- }
-}
-
-bool IsValid32BitImage(const base::FilePath& path) {
- base::MemoryMappedFile plugin_image;
-
- if (!plugin_image.InitializeAsImageSection(path))
- return false;
-
- base::win::PEImage image(plugin_image.data());
-
- PIMAGE_NT_HEADERS nt_headers = image.GetNTHeaders();
- return (nt_headers->FileHeader.Machine == IMAGE_FILE_MACHINE_I386);
-}
-
-// Returns true if the given plugins share at least one mime type. This is used
-// to differentiate newer versions of a plugin vs two plugins which happen to
-// have the same filename.
-bool HaveSharedMimeType(const WebPluginInfo& plugin1,
- const WebPluginInfo& plugin2) {
- for (size_t i = 0; i < plugin1.mime_types.size(); ++i) {
- for (size_t j = 0; j < plugin2.mime_types.size(); ++j) {
- if (plugin1.mime_types[i].mime_type == plugin2.mime_types[j].mime_type)
- return true;
- }
- }
-
- return false;
-}
-
-// Compares Windows style version strings (i.e. 1,2,3,4). Returns true if b's
-// version is newer than a's, or false if it's equal or older.
-bool IsNewerVersion(const base::string16& a, const base::string16& b) {
- std::vector<base::string16> a_ver = base::SplitString(
- a, base::string16(1, ','), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- std::vector<base::string16> b_ver = base::SplitString(
- b, base::string16(1, ','), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- if (a_ver.size() == 1 && b_ver.size() == 1) {
- a_ver = base::SplitString(
- a, base::string16(1, '.'), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- b_ver = base::SplitString(
- b, base::string16(1, '.'), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- }
- if (a_ver.size() != b_ver.size())
- return false;
- for (size_t i = 0; i < a_ver.size(); i++) {
- int cur_a, cur_b;
- base::StringToInt(a_ver[i], &cur_a);
- base::StringToInt(b_ver[i], &cur_b);
-
- if (cur_a > cur_b)
- return false;
- if (cur_a < cur_b)
- return true;
- }
- return false;
-}
-
-} // namespace
-
-bool PluginList::ReadWebPluginInfo(const base::FilePath& filename,
- WebPluginInfo* info) {
- // On windows, the way we get the mime types for the library is
- // to check the version information in the DLL itself. This
- // will be a string of the format: <type1>|<type2>|<type3>|...
- // For example:
- // video/quicktime|audio/aiff|image/jpeg
- scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfo(filename));
- if (!version_info) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Could not get version info for plugin "
- << filename.value();
- return false;
- }
-
- FileVersionInfoWin* version_info_win =
- static_cast<FileVersionInfoWin*>(version_info.get());
-
- info->name = version_info->product_name();
- info->desc = version_info->file_description();
- info->version = version_info->file_version();
- info->path = filename;
-
- // TODO(evan): Move the ParseMimeTypes code inline once Pepper is updated.
- if (!PluginList::ParseMimeTypes(
- base::UTF16ToASCII(version_info_win->GetStringValue(L"MIMEType")),
- base::UTF16ToASCII(version_info_win->GetStringValue(L"FileExtents")),
- version_info_win->GetStringValue(L"FileOpenName"),
- &info->mime_types)) {
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Plugin " << info->name << " has bad MIME types, skipping";
- return false;
- }
-
- return true;
-}
-
-void PluginList::GetPluginDirectories(
- std::vector<base::FilePath>* plugin_dirs) {
- if (PluginList::plugins_discovery_disabled_)
- return;
-
- // We use a set for uniqueness, which we require, over order, which we do not.
- std::set<base::FilePath> dirs;
-
- // Load from the application-specific area
- GetAppDirectory(&dirs);
-
- // Load from the executable area
- GetExeDirectory(&dirs);
-
- // Load Java
- GetJavaDirectory(&dirs);
-
- // Load firefox plugins too. This is mainly to try to locate
- // a pre-installed Flash player.
- GetFirefoxDirectory(&dirs);
-
- // Firefox hard-codes the paths of some popular plugins to ensure that
- // the plugins are found. We are going to copy this as well.
- GetAcrobatDirectory(&dirs);
- GetQuicktimeDirectory(&dirs);
- GetWindowsMediaDirectory(&dirs);
-
- for (std::set<base::FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
- plugin_dirs->push_back(*i);
-}
-
-void PluginList::GetPluginsInDir(
- const base::FilePath& path, std::vector<base::FilePath>* plugins) {
- WIN32_FIND_DATA find_file_data;
- HANDLE find_handle;
-
- base::string16 dir = path.value();
- // FindFirstFile requires that you specify a wildcard for directories.
- dir.append(L"\\NP*.DLL");
-
- find_handle = FindFirstFile(dir.c_str(), &find_file_data);
- if (find_handle == INVALID_HANDLE_VALUE)
- return;
-
- do {
- if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- base::FilePath filename = path.Append(find_file_data.cFileName);
- plugins->push_back(filename);
- }
- } while (FindNextFile(find_handle, &find_file_data) != 0);
-
- DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
- FindClose(find_handle);
-}
-
-void PluginList::GetPluginPathsFromRegistry(
- std::vector<base::FilePath>* plugins) {
- if (PluginList::plugins_discovery_disabled_)
- return;
-
- std::set<base::FilePath> plugin_dirs;
-
- // Search for plugins from HKCU and HKLM. THis will only find plugins that
- // are correctly registered in the correct WOW64 registry hive.
- GetPluginsInRegistryDirectory(HKEY_CURRENT_USER,
- kRegistryMozillaPlugins,
- 0,
- &plugin_dirs);
- GetPluginsInRegistryDirectory(HKEY_LOCAL_MACHINE,
- kRegistryMozillaPlugins,
- 0,
- &plugin_dirs);
-
- for (std::set<base::FilePath>::iterator i = plugin_dirs.begin();
- i != plugin_dirs.end(); ++i) {
- plugins->push_back(*i);
- }
-}
-
-bool PluginList::ShouldLoadPluginUsingPluginList(
- const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
- bool should_check_version = true;
- {
- base::AutoLock lock(lock_);
- should_check_version =
- std::find(extra_plugin_paths_.begin(), extra_plugin_paths_.end(),
- info.path) == extra_plugin_paths_.end();
- }
- // Version check for plugins that are not coming from |extra_plugin_paths_|.
- if (should_check_version) {
- for (size_t j = 0; j < plugins->size(); ++j) {
- base::FilePath::StringType plugin1 =
- base::ToLowerASCII((*plugins)[j].path.BaseName().value());
- base::FilePath::StringType plugin2 =
- base::ToLowerASCII(info.path.BaseName().value());
- if ((plugin1 == plugin2 && HaveSharedMimeType((*plugins)[j], info)) ||
- (plugin1 == kJavaDeploy1 && plugin2 == kJavaDeploy2) ||
- (plugin1 == kJavaDeploy2 && plugin2 == kJavaDeploy1)) {
- if (IsNewerVersion(info.version, (*plugins)[j].version))
- return false; // We have loaded a plugin whose version is newer.
- plugins->erase(plugins->begin() + j);
- break;
- }
- }
- }
-
- // The checks below only apply to NPAPI plugins.
- if (info.type != WebPluginInfo::PLUGIN_TYPE_NPAPI)
- return true;
-
- {
- base::AutoLock lock(lock_);
- // If the plugin is in our internal list we should load it.
- for (size_t i = 0; i < internal_plugins_.size(); ++i) {
- if (info.path == internal_plugins_[i].path)
- return true;
- }
- }
-
- // Troublemakers.
- base::FilePath::StringType filename =
- base::ToLowerASCII(info.path.BaseName().value());
- // Depends on XPCOM.
- if (filename == kMozillaActiveXPlugin)
- return false;
-
- // Disable the Yahoo Application State plugin as it crashes the plugin
- // process on return from NPObjectStub::OnInvoke. Please refer to
- // http://b/issue?id=1372124 for more information.
- if (filename == kYahooApplicationStatePlugin)
- return false;
-
- // Disable the WangWang protocol handler plugin (npww.dll) as it crashes
- // chrome during shutdown. Firefox also disables this plugin.
- // Please refer to http://code.google.com/p/chromium/issues/detail?id=3953
- // for more information.
- if (filename == kWanWangProtocolHandlerPlugin)
- return false;
-
- // We only work with newer versions of the Java plugin which use NPAPI only
- // and don't depend on XPCOM.
- if (filename == kJavaPlugin1 || filename == kJavaPlugin2) {
- std::vector<base::FilePath::StringType> ver = base::SplitString(
- info.version, base::FilePath::StringType(1, '.'),
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- int major, minor, update;
- if (ver.size() == 4 &&
- base::StringToInt(ver[0], &major) &&
- base::StringToInt(ver[1], &minor) &&
- base::StringToInt(ver[2], &update)) {
- if (major == 6 && minor == 0 && update < 120)
- return false; // Java SE6 Update 11 or older.
- }
- }
-
- // Special WMP handling:
- // If both the new and old WMP plugins exist, only load the new one.
- if (filename == kNewWMPPlugin) {
- for (size_t j = 0; j < plugins->size(); ++j) {
- if ((*plugins)[j].path.BaseName().value() == kOldWMPPlugin) {
- plugins->erase(plugins->begin() + j);
- break;
- }
- }
-
- } else if (filename == kOldWMPPlugin) {
- for (size_t j = 0; j < plugins->size(); ++j) {
- if ((*plugins)[j].path.BaseName().value() == kNewWMPPlugin)
- return false;
- }
- }
-
- base::FilePath plugin_path(info.path);
-#if defined(ARCH_CPU_X86_64)
- // The plugin in question could be a 32 bit plugin which we cannot load.
- if (IsValid32BitImage(base::MakeAbsoluteFilePath(plugin_path)))
- return false;
-#else
- // The plugin in question could be a 64 bit plugin which we cannot load.
- if (!IsValid32BitImage(base::MakeAbsoluteFilePath(plugin_path)))
- return false;
-#endif
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/common/plugin_process_messages.h b/chromium/content/common/plugin_process_messages.h
deleted file mode 100644
index a815b55ed30..00000000000
--- a/chromium/content/common/plugin_process_messages.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Multiply-included message file, hence no include guard.
-
-#include <stdint.h>
-
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "content/common/content_param_traits.h"
-#include "content/public/common/common_param_traits.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/ipc_message_macros.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "ui/gfx/native_widget_types.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-#define IPC_MESSAGE_START PluginProcessMsgStart
-
-//-----------------------------------------------------------------------------
-// PluginProcess messages
-// These are messages sent from the browser to the plugin process.
-// Tells the plugin process to create a new channel for communication with a
-// given renderer. The channel name is returned in a
-// PluginProcessHostMsg_ChannelCreated message. The renderer ID is passed so
-// that the plugin process reuses an existing channel to that process if it
-// exists. This ID is a unique opaque identifier generated by the browser
-// process.
-IPC_MESSAGE_CONTROL2(PluginProcessMsg_CreateChannel,
- int /* renderer_id */,
- bool /* off_the_record */)
-
-// Tells the plugin process to notify every connected renderer of the pending
-// shutdown, so we don't mistake it for a crash.
-IPC_MESSAGE_CONTROL0(PluginProcessMsg_NotifyRenderersOfPendingShutdown)
-
-IPC_MESSAGE_CONTROL3(PluginProcessMsg_ClearSiteData,
- std::string /* site */,
- uint64_t /* flags */,
- uint64_t /* max_age */)
-
-//-----------------------------------------------------------------------------
-// PluginProcessHost messages
-// These are messages sent from the plugin process to the browser process.
-// Response to a PluginProcessMsg_CreateChannel message.
-IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ChannelCreated,
- IPC::ChannelHandle /* channel_handle */)
-
-IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ChannelDestroyed,
- int /* renderer_id */)
-
-IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ClearSiteDataResult,
- bool /* success */)
-
-#if defined(OS_WIN)
-// Destroys the given window's parent on the UI thread.
-IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginWindowDestroyed,
- HWND /* window */,
- HWND /* parent */)
-#endif
-
-#if defined(OS_MACOSX)
-// On Mac OS X, we need the browser to keep track of plugin windows so
-// that it can add and remove them from stacking groups, hide and show the
-// menu bar, etc. We pass the window rect for convenience so that the
-// browser can easily tell if the window is fullscreen.
-
-// Notifies the browser that the plugin has shown a window.
-IPC_MESSAGE_CONTROL3(PluginProcessHostMsg_PluginShowWindow,
- uint32_t /* window ID */,
- gfx::Rect /* window rect */,
- bool /* modal */)
-
-// Notifies the browser that the plugin has hidden a window.
-IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginHideWindow,
- uint32_t /* window ID */,
- gfx::Rect /* window rect */)
-
-// Notifies the browser that a plugin instance has requested a cursor
-// visibility change.
-IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_PluginSetCursorVisibility,
- bool /* cursor visibility */)
-#endif
diff --git a/chromium/content/common/presentation/presentation_service.mojom b/chromium/content/common/presentation/presentation_service.mojom
index ae39815ccce..2c470a52ed3 100644
--- a/chromium/content/common/presentation/presentation_service.mojom
+++ b/chromium/content/common/presentation/presentation_service.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module presentation;
+module content.mojom;
struct PresentationSessionInfo {
string url;
@@ -16,6 +16,12 @@ enum PresentationConnectionState {
TERMINATED
};
+enum PresentationConnectionCloseReason {
+ CONNECTION_ERROR,
+ CLOSED,
+ WENT_AWAY
+};
+
enum PresentationErrorType {
NO_AVAILABLE_SCREENS,
SESSION_REQUEST_CANCELLED,
@@ -119,6 +125,12 @@ interface PresentationServiceClient {
OnConnectionStateChanged(PresentationSessionInfo connection,
PresentationConnectionState newState);
+ // Caled when the state of |connection| started on this frame has changed to
+ // CLOSED.
+ OnConnectionClosed(PresentationSessionInfo connection,
+ PresentationConnectionCloseReason reason,
+ string message);
+
// See PresentationService::ListenForSessionMessages.
OnSessionMessagesReceived(PresentationSessionInfo sessionInfo,
array<SessionMessage> messages);
diff --git a/chromium/content/common/process_control.mojom b/chromium/content/common/process_control.mojom
index efd0adc51ce..0734a6cd264 100644
--- a/chromium/content/common/process_control.mojom
+++ b/chromium/content/common/process_control.mojom
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
-import "mojo/shell/public/interfaces/application.mojom";
+import "mojo/shell/public/interfaces/shell_client.mojom";
interface ProcessControl {
- LoadApplication(string url, mojo.Application& request) => (bool success);
+ LoadApplication(string url,
+ mojo.shell.mojom.ShellClient& request) => (bool success);
};
diff --git a/chromium/content/common/process_type.cc b/chromium/content/common/process_type.cc
index 34019d453a6..ebce0e60141 100644
--- a/chromium/content/common/process_type.cc
+++ b/chromium/content/common/process_type.cc
@@ -15,8 +15,6 @@ std::string GetProcessTypeNameInEnglish(int type) {
return "Browser";
case PROCESS_TYPE_RENDERER:
return "Tab";
- case PROCESS_TYPE_PLUGIN:
- return "Plugin";
case PROCESS_TYPE_UTILITY:
return "Utility";
case PROCESS_TYPE_ZYGOTE:
diff --git a/chromium/content/common/push_messaging_messages.h b/chromium/content/common/push_messaging_messages.h
index 38a39e8cb11..df88b2f2a55 100644
--- a/chromium/content/common/push_messaging_messages.h
+++ b/chromium/content/common/push_messaging_messages.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "content/public/common/push_messaging_status.h"
+#include "content/public/common/push_subscription_options.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h"
@@ -29,6 +30,11 @@ IPC_ENUM_TRAITS_MAX_VALUE(
blink::WebPushError::ErrorType,
blink::WebPushError::ErrorType::ErrorTypeLast)
+IPC_STRUCT_TRAITS_BEGIN(content::PushSubscriptionOptions)
+ IPC_STRUCT_TRAITS_MEMBER(user_visible_only)
+ IPC_STRUCT_TRAITS_MEMBER(sender_info)
+IPC_STRUCT_TRAITS_END()
+
// Messages sent from the browser to the child process.
IPC_MESSAGE_ROUTED4(PushMessagingMsg_SubscribeFromDocumentSuccess,
@@ -80,17 +86,16 @@ IPC_MESSAGE_CONTROL2(PushMessagingMsg_GetPermissionStatusError,
// Messages sent from the child process to the browser.
-IPC_MESSAGE_CONTROL5(PushMessagingHostMsg_SubscribeFromDocument,
+IPC_MESSAGE_CONTROL4(PushMessagingHostMsg_SubscribeFromDocument,
int32_t /* render_frame_id */,
int32_t /* request_id */,
- std::string /* sender_id */,
- bool /* user_visible */,
+ content::PushSubscriptionOptions /* options */,
int64_t /* service_worker_registration_id */)
IPC_MESSAGE_CONTROL3(PushMessagingHostMsg_SubscribeFromWorker,
int32_t /* request_id */,
int64_t /* service_worker_registration_id */,
- bool /* user_visible */)
+ content::PushSubscriptionOptions /* options */)
IPC_MESSAGE_CONTROL2(PushMessagingHostMsg_Unsubscribe,
int32_t /* request_id */,
diff --git a/chromium/content/common/render_frame_setup.mojom b/chromium/content/common/render_frame_setup.mojom
index abe4f652f32..748f733096c 100644
--- a/chromium/content/common/render_frame_setup.mojom
+++ b/chromium/content/common/render_frame_setup.mojom
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
-import "mojo/shell/public/interfaces/service_provider.mojom";
+import "mojo/shell/public/interfaces/interface_provider.mojom";
interface RenderFrameSetup {
- ExchangeServiceProviders(int32 frame_routing_id,
- mojo.ServiceProvider& services,
- mojo.ServiceProvider exposed_services);
+ ExchangeInterfaceProviders(
+ int32 frame_routing_id,
+ mojo.shell.mojom.InterfaceProvider& remote_interfaces,
+ mojo.shell.mojom.InterfaceProvider local_interfaces);
};
diff --git a/chromium/content/common/resize_params.cc b/chromium/content/common/resize_params.cc
new file mode 100644
index 00000000000..ea9f18fb65b
--- /dev/null
+++ b/chromium/content/common/resize_params.cc
@@ -0,0 +1,20 @@
+// Copyright 2015 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 "content/common/resize_params.h"
+
+namespace content {
+
+ResizeParams::ResizeParams()
+ : top_controls_shrink_blink_size(false),
+ top_controls_height(0.f),
+ is_fullscreen_granted(false),
+ display_mode(blink::WebDisplayModeUndefined),
+ needs_resize_ack(false) {}
+
+ResizeParams::ResizeParams(const ResizeParams& other) = default;
+
+ResizeParams::~ResizeParams() {}
+
+} // namespace content
diff --git a/chromium/content/common/resize_params.h b/chromium/content/common/resize_params.h
new file mode 100644
index 00000000000..f9eb07c247d
--- /dev/null
+++ b/chromium/content/common/resize_params.h
@@ -0,0 +1,58 @@
+// Copyright 2015 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 CONTENT_COMMON_RESIZE_PARAMS_H_
+#define CONTENT_COMMON_RESIZE_PARAMS_H_
+
+#include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebDisplayMode.h"
+#include "third_party/WebKit/public/platform/WebScreenInfo.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace content {
+
+struct CONTENT_EXPORT ResizeParams {
+ ResizeParams();
+ ResizeParams(const ResizeParams& other);
+ ~ResizeParams();
+
+ // Information about the screen (dpi, depth, etc..).
+ blink::WebScreenInfo screen_info;
+
+ // The size of the renderer.
+ gfx::Size new_size;
+
+ // The size of the view's backing surface in non-DPI-adjusted pixels.
+ gfx::Size physical_backing_size;
+
+ // Whether or not Blink's viewport size should be shrunk by the height of the
+ // URL-bar (always false on platforms where URL-bar hiding isn't supported).
+ bool top_controls_shrink_blink_size;
+
+ // The height of the top controls (always 0 on platforms where URL-bar hiding
+ // isn't supported).
+ float top_controls_height;
+
+ // The size of the visible viewport, which may be smaller than the view if the
+ // view is partially occluded (e.g. by a virtual keyboard). The size is in
+ // DPI-adjusted pixels.
+ gfx::Size visible_viewport_size;
+
+ // The resizer rect.
+ gfx::Rect resizer_rect;
+
+ // Indicates whether tab-initiated fullscreen was granted.
+ bool is_fullscreen_granted;
+
+ // The display mode.
+ blink::WebDisplayMode display_mode;
+
+ // If set, requests the renderer to reply with a ViewHostMsg_UpdateRect
+ // with the ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK bit set in flags.
+ bool needs_resize_ack;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_RESIZE_PARAMS_H_
diff --git a/chromium/content/common/resource_messages.cc b/chromium/content/common/resource_messages.cc
index da92b97b09b..2c0cbe12b7b 100644
--- a/chromium/content/common/resource_messages.cc
+++ b/chromium/content/common/resource_messages.cc
@@ -9,8 +9,9 @@
namespace IPC {
-void ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Write(
- Message* m, const param_type& p) {
+void ParamTraits<scoped_refptr<net::HttpResponseHeaders>>::Write(
+ base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.get() != NULL);
if (p.get()) {
// Do not disclose Set-Cookie headers over IPC.
@@ -19,7 +20,7 @@ void ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Write(
}
bool ParamTraits<scoped_refptr<net::HttpResponseHeaders>>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
bool has_object;
@@ -35,7 +36,8 @@ void ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Log(
l->append("<HttpResponseHeaders>");
}
-void ParamTraits<storage::DataElement>::Write(Message* m, const param_type& p) {
+void ParamTraits<storage::DataElement>::Write(base::Pickle* m,
+ const param_type& p) {
WriteParam(m, static_cast<int>(p.type()));
switch (p.type()) {
case storage::DataElement::TYPE_BYTES: {
@@ -77,7 +79,7 @@ void ParamTraits<storage::DataElement>::Write(Message* m, const param_type& p) {
}
}
-bool ParamTraits<storage::DataElement>::Read(const Message* m,
+bool ParamTraits<storage::DataElement>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
int type;
@@ -160,8 +162,9 @@ void ParamTraits<storage::DataElement>::Log(const param_type& p,
l->append("<storage::DataElement>");
}
-void ParamTraits<scoped_refptr<content::ResourceDevToolsInfo> >::Write(
- Message* m, const param_type& p) {
+void ParamTraits<scoped_refptr<content::ResourceDevToolsInfo>>::Write(
+ base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.get() != NULL);
if (p.get()) {
WriteParam(m, p->http_status_code);
@@ -174,7 +177,7 @@ void ParamTraits<scoped_refptr<content::ResourceDevToolsInfo> >::Write(
}
bool ParamTraits<scoped_refptr<content::ResourceDevToolsInfo>>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
bool has_object;
@@ -203,8 +206,8 @@ void ParamTraits<scoped_refptr<content::ResourceDevToolsInfo> >::Log(
l->append(")");
}
-void ParamTraits<net::LoadTimingInfo>::Write(
- Message* m, const param_type& p) {
+void ParamTraits<net::LoadTimingInfo>::Write(base::Pickle* m,
+ const param_type& p) {
WriteParam(m, p.socket_log_id);
WriteParam(m, p.socket_reused);
WriteParam(m, p.request_start_time.is_null());
@@ -225,7 +228,7 @@ void ParamTraits<net::LoadTimingInfo>::Write(
WriteParam(m, p.receive_headers_end);
}
-bool ParamTraits<net::LoadTimingInfo>::Read(const Message* m,
+bool ParamTraits<net::LoadTimingInfo>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
bool has_no_times;
@@ -288,8 +291,8 @@ void ParamTraits<net::LoadTimingInfo>::Log(const param_type& p,
l->append(")");
}
-void ParamTraits<scoped_refptr<content::ResourceRequestBody> >::Write(
- Message* m,
+void ParamTraits<scoped_refptr<content::ResourceRequestBody>>::Write(
+ base::Pickle* m,
const param_type& p) {
WriteParam(m, p.get() != NULL);
if (p.get()) {
@@ -299,7 +302,7 @@ void ParamTraits<scoped_refptr<content::ResourceRequestBody> >::Write(
}
bool ParamTraits<scoped_refptr<content::ResourceRequestBody>>::Read(
- const Message* m,
+ const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
bool has_object;
diff --git a/chromium/content/common/resource_messages.h b/chromium/content/common/resource_messages.h
index 44e4a611fc7..9c53b361a33 100644
--- a/chromium/content/common/resource_messages.h
+++ b/chromium/content/common/resource_messages.h
@@ -39,40 +39,50 @@ namespace IPC {
template <>
struct ParamTraits<scoped_refptr<net::HttpResponseHeaders> > {
typedef scoped_refptr<net::HttpResponseHeaders> param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<storage::DataElement> {
typedef storage::DataElement param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<scoped_refptr<content::ResourceDevToolsInfo> > {
typedef scoped_refptr<content::ResourceDevToolsInfo> param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<net::LoadTimingInfo> {
typedef net::LoadTimingInfo param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
struct ParamTraits<scoped_refptr<content::ResourceRequestBody> > {
typedef scoped_refptr<content::ResourceRequestBody> param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
static void Log(const param_type& p, std::string* l);
};
@@ -139,6 +149,8 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceResponseInfo)
IPC_STRUCT_TRAITS_MEMBER(response_type_via_service_worker)
IPC_STRUCT_TRAITS_MEMBER(service_worker_start_time)
IPC_STRUCT_TRAITS_MEMBER(service_worker_ready_time)
+ IPC_STRUCT_TRAITS_MEMBER(is_in_cache_storage)
+ IPC_STRUCT_TRAITS_MEMBER(cache_storage_cache_name)
IPC_STRUCT_TRAITS_MEMBER(proxy_server)
IPC_STRUCT_TRAITS_MEMBER(is_using_lofi)
IPC_STRUCT_TRAITS_END()
@@ -149,6 +161,7 @@ IPC_STRUCT_TRAITS_BEGIN(net::RedirectInfo)
IPC_STRUCT_TRAITS_MEMBER(new_url)
IPC_STRUCT_TRAITS_MEMBER(new_first_party_for_cookies)
IPC_STRUCT_TRAITS_MEMBER(new_referrer)
+ IPC_STRUCT_TRAITS_MEMBER(referred_token_binding_host)
IPC_STRUCT_TRAITS_END()
// Parameters for a resource request.
@@ -213,6 +226,10 @@ IPC_STRUCT_BEGIN(ResourceHostMsg_Request)
// or kInvalidServiceWorkerProviderId.
IPC_STRUCT_MEMBER(int, service_worker_provider_id)
+ // True if the request originated from a Service Worker, e.g. due to a
+ // fetch() in the Service Worker script.
+ IPC_STRUCT_MEMBER(bool, originated_from_service_worker)
+
// True if the request should not be handled by the ServiceWorker.
IPC_STRUCT_MEMBER(bool, skip_service_worker)
@@ -284,6 +301,11 @@ IPC_STRUCT_BEGIN(ResourceHostMsg_Request)
// Whether or not to request a LoFi version of the resource or let the browser
// decide.
IPC_STRUCT_MEMBER(content::LoFiState, lofi_state)
+
+ // PlzNavigate: the stream url associated with a navigation. Used to get
+ // access to the body of the response that has already been fetched by the
+ // browser.
+ IPC_STRUCT_MEMBER(GURL, resource_body_stream_url)
IPC_STRUCT_END()
// Parameters for a ResourceMsg_RequestComplete
@@ -355,6 +377,19 @@ IPC_MESSAGE_CONTROL4(ResourceMsg_SetDataBuffer,
IPC_MESSAGE_CONTROL2(ResourceMsg_DataReceivedDebug,
int /* request_id */,
int /* data_offset */)
+IPC_MESSAGE_CONTROL4(ResourceMsg_DataReceivedDebug2,
+ int /* request_id */,
+ int /* data_offset */,
+ int /* data_length */,
+ int /* encoded_data_length */)
+
+// Sent when a chunk of data from a resource request is ready, and the resource
+// is expected to be small enough to fit in the inlined buffer.
+// The data is sent as a part of IPC message.
+IPC_MESSAGE_CONTROL3(ResourceMsg_InlinedDataChunkReceived,
+ int /* request_id */,
+ std::vector<char> /* data */,
+ int /* encoded_data_length */)
// Sent when some data from a resource request is ready. The data offset and
// length specify a byte range into the shared memory buffer provided by the
diff --git a/chromium/content/common/sandbox_init_mac.cc b/chromium/content/common/sandbox_init_mac.cc
index c49aa80685e..36a4058c35e 100644
--- a/chromium/content/common/sandbox_init_mac.cc
+++ b/chromium/content/common/sandbox_init_mac.cc
@@ -53,8 +53,7 @@ bool GetSandboxTypeFromCommandLine(int* sandbox_type,
if (command_line.HasSwitch(switches::kDisableGpuSandbox))
return false;
*sandbox_type = SANDBOX_TYPE_GPU;
- } else if ((process_type == switches::kPluginProcess) ||
- (process_type == switches::kPpapiBrokerProcess)) {
+ } else if (process_type == switches::kPpapiBrokerProcess) {
return false;
} else if (process_type == switches::kPpapiPluginProcess) {
*sandbox_type = SANDBOX_TYPE_PPAPI;
@@ -75,12 +74,4 @@ bool InitializeSandbox() {
return InitializeSandbox(sandbox_type, allowed_dir);
}
-bool BrokerDuplicateSharedMemoryHandle(
- const base::SharedMemoryHandle& source_handle,
- base::ProcessId target_process_id,
- base::SharedMemoryHandle* target_handle) {
- *target_handle = base::SharedMemory::DuplicateHandle(source_handle);
- return base::SharedMemory::IsHandleValid(*target_handle);
-}
-
} // namespace content
diff --git a/chromium/content/common/sandbox_init_win.cc b/chromium/content/common/sandbox_init_win.cc
index 78c1fef251d..16e3e4afbd4 100644
--- a/chromium/content/common/sandbox_init_win.cc
+++ b/chromium/content/common/sandbox_init_win.cc
@@ -42,19 +42,4 @@ bool InitializeSandbox(sandbox::SandboxInterfaceInfo* sandbox_info) {
return InitTargetServices(target_services);
}
-bool BrokerDuplicateSharedMemoryHandle(
- const base::SharedMemoryHandle& source_handle,
- base::ProcessId target_process_id,
- base::SharedMemoryHandle* target_handle) {
- HANDLE duped_handle;
- if (!BrokerDuplicateHandle(
- source_handle.GetHandle(), target_process_id, &duped_handle,
- FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY, 0)) {
- return false;
- }
-
- *target_handle = base::SharedMemoryHandle(duped_handle, target_process_id);
- return true;
-}
-
} // namespace content
diff --git a/chromium/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc b/chromium/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
index c3b1605fc7d..5f9813f5808 100644
--- a/chromium/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
+++ b/chromium/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
@@ -4,17 +4,51 @@
#include "content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/net.h>
+#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include "build/build_config.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+using sandbox::bpf_dsl::AllOf;
using sandbox::bpf_dsl::Allow;
+using sandbox::bpf_dsl::AnyOf;
+using sandbox::bpf_dsl::Arg;
+using sandbox::bpf_dsl::BoolExpr;
+using sandbox::bpf_dsl::If;
+using sandbox::bpf_dsl::Error;
using sandbox::bpf_dsl::ResultExpr;
namespace content {
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC O_CLOEXEC
+#endif
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK O_NONBLOCK
+#endif
+
+namespace {
+
+// Restricts the arguments to sys_socket() to AF_UNIX. Returns a BoolExpr that
+// evaluates to true if the syscall should be allowed.
+BoolExpr RestrictSocketArguments(const Arg<int>& domain,
+ const Arg<int>& type,
+ const Arg<int>& protocol) {
+ const int kSockFlags = SOCK_CLOEXEC | SOCK_NONBLOCK;
+ return AllOf(domain == AF_UNIX,
+ AnyOf((type & ~kSockFlags) == SOCK_DGRAM,
+ (type & ~kSockFlags) == SOCK_STREAM),
+ protocol == 0);
+}
+
+} // namespace
+
SandboxBPFBasePolicyAndroid::SandboxBPFBasePolicyAndroid()
: SandboxBPFBasePolicy() {}
@@ -27,11 +61,19 @@ ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const {
// TODO(rsesek): restrict clone parameters.
case __NR_clone:
case __NR_epoll_pwait:
+ case __NR_fdatasync:
case __NR_flock:
+ case __NR_fsync:
+ case __NR_ftruncate:
+#if defined(__i386__) || defined(__arm__) || defined(__mips__)
+ case __NR_ftruncate64:
+#endif
#if defined(__x86_64__) || defined(__aarch64__)
case __NR_newfstatat:
+ case __NR_getdents64:
#elif defined(__i386__) || defined(__arm__) || defined(__mips__)
case __NR_fstatat64:
+ case __NR_getdents:
#endif
case __NR_getpriority:
case __NR_ioctl:
@@ -46,7 +88,11 @@ ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const {
#endif
case __NR_openat:
case __NR_pread64:
+ case __NR_pwrite64:
case __NR_rt_sigtimedwait:
+ case __NR_sched_getparam:
+ case __NR_sched_getscheduler:
+ case __NR_sched_setscheduler:
case __NR_setpriority:
case __NR_set_tid_address:
case __NR_sigaltstack:
@@ -56,10 +102,49 @@ ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const {
case __NR_getrlimit:
#endif
case __NR_uname:
+
+ // Permit socket operations so that renderers can connect to logd and
+ // debuggerd. The arguments to socket() are further restricted below.
+ // Note that on i386, both of these calls map to __NR_socketcall, which
+ // is demultiplexed below.
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
+ defined(__mips__)
+ case __NR_getsockopt:
+ case __NR_connect:
+ case __NR_socket:
+#endif
+
+ // Ptrace is allowed so the Breakpad Microdumper can fork in a renderer
+ // and then ptrace the parent.
+ case __NR_ptrace:
override_and_allow = true;
break;
}
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
+ defined(__mips__)
+ if (sysno == __NR_socket) {
+ const Arg<int> domain(0);
+ const Arg<int> type(1);
+ const Arg<int> protocol(2);
+ return If(RestrictSocketArguments(domain, type, protocol), Allow())
+ .Else(Error(EPERM));
+ }
+#elif defined(__i386__)
+ if (sysno == __NR_socketcall) {
+ const Arg<int> socketcall(0);
+ const Arg<int> domain(1);
+ const Arg<int> type(2);
+ const Arg<int> protocol(3);
+ return If(socketcall == SYS_CONNECT, Allow())
+ .ElseIf(AllOf(socketcall == SYS_SOCKET,
+ RestrictSocketArguments(domain, type, protocol)),
+ Allow())
+ .ElseIf(socketcall == SYS_GETSOCKOPT, Allow())
+ .Else(Error(EPERM));
+ }
+#endif
+
if (override_and_allow)
return Allow();
diff --git a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
index e799273919a..b6a960ceef3 100644
--- a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
+++ b/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
@@ -15,8 +15,17 @@
#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
#include "sandbox/linux/system_headers/linux_syscalls.h"
-#if defined(USE_VGEM_MAP)
-#include <libdrm/vgem_drm.h>
+#if defined(OS_CHROMEOS)
+// TODO(vignatti): replace the local definitions below with #include
+// <linux/dma-buf.h> once kernel version 4.6 becomes widely used.
+#include <linux/types.h>
+
+struct local_dma_buf_sync {
+ __u64 flags;
+};
+#define LOCAL_DMA_BUF_BASE 'b'
+#define LOCAL_DMA_BUF_IOCTL_SYNC \
+ _IOW(LOCAL_DMA_BUF_BASE, 0, struct local_dma_buf_sync)
#endif
using sandbox::SyscallSets;
@@ -34,12 +43,9 @@ ResultExpr RestrictIoctl() {
return Switch(request)
.SANDBOX_BPF_DSL_CASES((static_cast<unsigned long>(TCGETS), FIONREAD),
Allow())
-#if defined(USE_VGEM_MAP)
- // Type of DRM_IOCTL_XXX is unsigned long on IA and unsigned int on ARM.
+#if defined(OS_CHROMEOS)
.SANDBOX_BPF_DSL_CASES(
- (static_cast<unsigned long>(DRM_IOCTL_GEM_CLOSE),
- DRM_IOCTL_VGEM_MODE_MAP_DUMB, DRM_IOCTL_PRIME_FD_TO_HANDLE),
- Allow())
+ (static_cast<unsigned long>(LOCAL_DMA_BUF_IOCTL_SYNC)), Allow())
#endif
.Default(sandbox::CrashSIGSYSIoctl());
}
@@ -60,7 +66,8 @@ ResultExpr RendererProcessPolicy::EvaluateSyscall(int sysno) const {
// Allow the system calls below.
case __NR_fdatasync:
case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
+ defined(__aarch64__)
case __NR_getrlimit:
#endif
#if defined(__i386__) || defined(__arm__)
diff --git a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc
index 3ead1c899d2..13367964e64 100644
--- a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc
+++ b/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc
@@ -32,7 +32,8 @@ ResultExpr UtilityProcessPolicy::EvaluateSyscall(int sysno) const {
// Allow the system calls below.
case __NR_fdatasync:
case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
+ defined(__aarch64__)
case __NR_getrlimit:
#endif
#if defined(__i386__) || defined(__arm__)
diff --git a/chromium/content/common/sandbox_linux/sandbox_linux.h b/chromium/content/common/sandbox_linux/sandbox_linux.h
index 0a80479799f..7ce723b3771 100644
--- a/chromium/content/common/sandbox_linux/sandbox_linux.h
+++ b/chromium/content/common/sandbox_linux/sandbox_linux.h
@@ -42,7 +42,7 @@ namespace content {
class LinuxSandbox {
public:
// This is a list of sandbox IPC methods which the renderer may send to the
- // sandbox host. See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
+ // sandbox host. See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md
// This isn't the full list, values < 32 are reserved for methods called from
// Skia.
enum LinuxSandboxIPCMethods {
diff --git a/chromium/content/common/sandbox_mac.h b/chromium/content/common/sandbox_mac.h
index bac23f0df8c..afda387549f 100644
--- a/chromium/content/common/sandbox_mac.h
+++ b/chromium/content/common/sandbox_mac.h
@@ -50,9 +50,6 @@ class CONTENT_EXPORT SandboxCompiler {
bool CompileAndApplyProfile(std::string* error);
private:
- // Frees all of the system resources allocated for the sandbox.
- void FreeSandboxResources(void* profile, void* params, char* error);
-
// Storage of the key/value pairs of strings that are used in the sandbox
// profile.
std::map<std::string, std::string> params_map_;
diff --git a/chromium/content/common/sandbox_mac.mm b/chromium/content/common/sandbox_mac.mm
index ca915a739e8..6a7f2cfcc74 100644
--- a/chromium/content/common/sandbox_mac.mm
+++ b/chromium/content/common/sandbox_mac.mm
@@ -47,14 +47,10 @@ extern "C" {
void CGSSetDenyWindowServerConnections(bool);
void CGSShutdownServerConnections();
-void* sandbox_create_params();
-int sandbox_set_param(void* params, const char* key, const char* value);
-void* sandbox_compile_string(const char* profile_str,
- void* params,
- char** error);
-int sandbox_apply(void* profile);
-void sandbox_free_params(void* params);
-void sandbox_free_profile(void* profile);
+int sandbox_init_with_parameters(const char* profile,
+ uint64_t flags,
+ const char* const parameters[],
+ char** errorbuf);
};
namespace content {
@@ -68,14 +64,6 @@ struct SandboxTypeToResourceIDMapping {
int sandbox_profile_resource_id;
};
-// This is the internal definition of the structure used by sandbox parameters
-// on OS X 10.6.
-struct SandboxParams {
- void* buf;
- size_t count;
- size_t size;
-};
-
// Mapping from sandbox process types to resource IDs containing the sandbox
// profile for all process types known to content.
SandboxTypeToResourceIDMapping kDefaultSandboxTypeToResourceIDMapping[] = {
@@ -153,58 +141,27 @@ bool SandboxCompiler::InsertStringParam(const std::string& key,
return params_map_.insert(std::make_pair(key, value)).second;
}
-void SandboxCompiler::FreeSandboxResources(void* profile,
- void* params,
- char* error) {
- if (error)
- sandbox_free_error(error);
- if (params)
- sandbox_free_params(params);
- if (profile)
- sandbox_free_profile(profile);
-}
-
bool SandboxCompiler::CompileAndApplyProfile(std::string* error) {
char* error_internal = nullptr;
- void* profile = nullptr;
- void* params = nullptr;
-
- if (!params_map_.empty()) {
- if (base::mac::IsOSSnowLeopard()) {
- // This is a workaround for 10.6, see crbug.com/509114.
- // Check that there is no integer overflow.
- base::CheckedNumeric<size_t> checked_size = params_map_.size();
- checked_size *= 2;
- if (!checked_size.IsValid())
- return false;
-
- SandboxParams* internal_params =
- static_cast<SandboxParams*>(malloc(sizeof(SandboxParams)));
- internal_params->buf = calloc(checked_size.ValueOrDie(), sizeof(void*));
- internal_params->count = 0;
- internal_params->size = checked_size.ValueOrDie();
- params = internal_params;
- } else {
- params = sandbox_create_params();
- if (!params)
- return false;
- }
+ std::vector<const char*> params;
- for (const auto& kv : params_map_)
- sandbox_set_param(params, kv.first.c_str(), kv.second.c_str());
+ for (const auto& kv : params_map_) {
+ params.push_back(kv.first.c_str());
+ params.push_back(kv.second.c_str());
}
+ // The parameters array must be null terminated.
+ params.push_back(static_cast<const char*>(0));
- profile =
- sandbox_compile_string(profile_str_.c_str(), params, &error_internal);
- if (!profile) {
+ if (sandbox_init_with_parameters(profile_str_.c_str(), 0, params.data(),
+ &error_internal)) {
error->assign(error_internal);
- FreeSandboxResources(profile, params, error_internal);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ sandbox_free_error(error_internal);
+#pragma clang diagnostic pop
return false;
}
-
- int result = sandbox_apply(profile);
- FreeSandboxResources(profile, params, error_internal);
- return result == 0;
+ return true;
}
// static
@@ -534,16 +491,6 @@ bool Sandbox::EnableSandbox(int sandbox_type,
if (!compiler.InsertBooleanParam("ELCAP_OR_LATER", elcap_or_later))
return false;
-#if defined(COMPONENT_BUILD)
- // dlopen() fails without file-read-metadata access if the executable image
- // contains LC_RPATH load commands. The components build uses those.
- // See http://crbug.com/127465
- if (base::mac::IsOSSnowLeopard()) {
- if (!compiler.InsertBooleanParam("COMPONENT_BUILD_WORKAROUND", true))
- return false;
- }
-#endif
-
// Initialize sandbox.
std::string error_str;
bool success = compiler.CompileAndApplyProfile(&error_str);
diff --git a/chromium/content/common/sandbox_mac_diraccess_unittest.mm b/chromium/content/common/sandbox_mac_diraccess_unittest.mm
index 17be671801a..205e1cbc0b9 100644
--- a/chromium/content/common/sandbox_mac_diraccess_unittest.mm
+++ b/chromium/content/common/sandbox_mac_diraccess_unittest.mm
@@ -13,6 +13,7 @@ extern "C" {
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process/kill.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/content/common/sandbox_mac_system_access_unittest.mm b/chromium/content/common/sandbox_mac_system_access_unittest.mm
index 02980715609..b37b967d2b9 100644
--- a/chromium/content/common/sandbox_mac_system_access_unittest.mm
+++ b/chromium/content/common/sandbox_mac_system_access_unittest.mm
@@ -9,11 +9,13 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/strings/sys_string_conversions.h"
#include "content/common/sandbox_mac.h"
#include "content/common/sandbox_mac_unittest_helper.h"
#include "crypto/openssl_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#import "ui/base/clipboard/clipboard_util_mac.h"
namespace content {
@@ -69,15 +71,16 @@ void MacSandboxedClipboardTestCase::SetTestData(const char* test_data) {
}
TEST_F(MacSandboxTest, ClipboardAccess) {
- NSPasteboard* pb = [NSPasteboard pasteboardWithUniqueName];
- EXPECT_EQ([[pb types] count], 0U);
+ scoped_refptr<ui::UniquePasteboard> pb = new ui::UniquePasteboard;
+ ASSERT_TRUE(pb->get());
+ EXPECT_EQ([[pb->get() types] count], 0U);
- std::string pasteboard_name = base::SysNSStringToUTF8([pb name]);
+ std::string pasteboard_name = base::SysNSStringToUTF8([pb->get() name]);
EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedClipboardTestCase",
pasteboard_name.c_str()));
// After executing the test, the clipboard should still be empty.
- EXPECT_EQ([[pb types] count], 0U);
+ EXPECT_EQ([[pb->get() types] count], 0U);
}
//--------------------- File Access Sandboxing ----------------------
diff --git a/chromium/content/common/sandbox_util.cc b/chromium/content/common/sandbox_util.cc
index 4b1dcef4a91..75b3977f4d6 100644
--- a/chromium/content/common/sandbox_util.cc
+++ b/chromium/content/common/sandbox_util.cc
@@ -6,6 +6,7 @@
#include "build/build_config.h"
#include "content/public/common/sandbox_init.h"
+#include "ipc/ipc_platform_file.h"
#if defined(OS_POSIX)
#include <unistd.h>
@@ -17,30 +18,7 @@ IPC::PlatformFileForTransit BrokerGetFileHandleForProcess(
base::PlatformFile handle,
base::ProcessId target_process_id,
bool should_close_source) {
- IPC::PlatformFileForTransit out_handle;
-#if defined(OS_WIN)
- DWORD options = DUPLICATE_SAME_ACCESS;
- if (should_close_source)
- options |= DUPLICATE_CLOSE_SOURCE;
- if (!content::BrokerDuplicateHandle(handle, target_process_id, &out_handle,
- 0, options)) {
- out_handle = IPC::InvalidPlatformFileForTransit();
- }
-#elif defined(OS_POSIX)
- // If asked to close the source, we can simply re-use the source fd instead of
- // dup()ing and close()ing.
- // When we're not closing the source, we need to duplicate the handle and take
- // ownership of that. The reason is that this function is often used to
- // generate IPC messages, and the handle must remain valid until it's sent to
- // the other process from the I/O thread. Without the dup, calling code might
- // close the source handle before the message is sent, creating a race
- // condition.
- int fd = should_close_source ? handle : ::dup(handle);
- out_handle = base::FileDescriptor(fd, true);
-#else
- #error Not implemented.
-#endif
- return out_handle;
+ return IPC::GetPlatformFileForTransit(handle, should_close_source);
}
} // namespace content
diff --git a/chromium/content/common/sandbox_win.cc b/chromium/content/common/sandbox_win.cc
index 92a5a241f57..fe266227ad8 100644
--- a/chromium/content/common/sandbox_win.cc
+++ b/chromium/content/common/sandbox_win.cc
@@ -32,7 +32,6 @@
#include "content/common/content_switches_internal.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/dwrite_font_platform_win.h"
#include "content/public/common/sandbox_init.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "sandbox/win/src/process_mitigations.h"
@@ -403,7 +402,6 @@ bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) {
if (result != sandbox::SBOX_ALL_OK)
return false;
-
sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
if (base::win::GetVersion() > base::win::VERSION_XP) {
// On 2003/Vista the initial token has to be restricted if the main
@@ -415,6 +413,7 @@ bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) {
// Prevents the renderers from manipulating low-integrity processes.
policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED);
policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
+ policy->SetLockdownDefaultDacl();
if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(true)) {
DLOG(WARNING) << "Failed to apply desktop security to the renderer";
@@ -665,7 +664,8 @@ bool InitTargetServices(sandbox::TargetServices* target_services) {
base::Process StartSandboxedProcess(
SandboxedProcessLauncherDelegate* delegate,
- base::CommandLine* cmd_line) {
+ base::CommandLine* cmd_line,
+ const base::HandlesToInheritVector& handles_to_inherit) {
DCHECK(delegate);
const base::CommandLine& browser_command_line =
*base::CommandLine::ForCurrentProcess();
@@ -684,20 +684,41 @@ base::Process StartSandboxedProcess(
if ((!delegate->ShouldSandbox()) ||
browser_command_line.HasSwitch(switches::kNoSandbox) ||
cmd_line->HasSwitch(switches::kNoSandbox)) {
- base::Process process =
- base::LaunchProcess(*cmd_line, base::LaunchOptions());
+ base::LaunchOptions options;
+
+ base::HandlesToInheritVector handles = handles_to_inherit;
+ if (!handles_to_inherit.empty()) {
+ options.inherit_handles = true;
+ options.handles_to_inherit = &handles;
+ }
+ base::Process process = base::LaunchProcess(*cmd_line, options);
+
// TODO(rvargas) crbug.com/417532: Don't share a raw handle.
g_broker_services->AddTargetPeer(process.Handle());
- return process.Pass();
+ return process;
}
sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy();
- sandbox::MitigationFlags mitigations = sandbox::MITIGATION_HEAP_TERMINATE |
- sandbox::MITIGATION_BOTTOM_UP_ASLR |
- sandbox::MITIGATION_DEP |
- sandbox::MITIGATION_DEP_NO_ATL_THUNK |
- sandbox::MITIGATION_SEHOP;
+ // Add any handles to be inherited to the policy.
+ for (HANDLE handle : handles_to_inherit)
+ policy->AddHandleToShare(handle);
+
+ // Pre-startup mitigations.
+ sandbox::MitigationFlags mitigations =
+ sandbox::MITIGATION_HEAP_TERMINATE |
+ sandbox::MITIGATION_BOTTOM_UP_ASLR |
+ sandbox::MITIGATION_DEP |
+ sandbox::MITIGATION_DEP_NO_ATL_THUNK |
+ sandbox::MITIGATION_SEHOP |
+ sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE |
+ sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE |
+ sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL;
+#if !defined(NACL_WIN64)
+ // Don't block font loading with GDI.
+ if (!gfx::win::ShouldUseDirectWrite())
+ mitigations ^= sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE;
+#endif
if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK)
return base::Process();
@@ -710,6 +731,7 @@ base::Process StartSandboxedProcess(
}
#endif
+ // Post-startup mitigations.
mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
sandbox::MITIGATION_DLL_SEARCH_ORDER;
@@ -724,6 +746,9 @@ base::Process StartSandboxedProcess(
}
#if !defined(NACL_WIN64)
+ // NOTE: This is placed at function scope so that it stays alive through
+ // process launch.
+ base::SharedMemory direct_write_font_cache_section;
if (type_str == switches::kRendererProcess ||
type_str == switches::kPpapiPluginProcess) {
if (gfx::win::ShouldUseDirectWrite()) {
@@ -732,25 +757,6 @@ base::Process StartSandboxedProcess(
true,
sandbox::TargetPolicy::FILES_ALLOW_READONLY,
policy);
-
- if (!ShouldUseDirectWriteFontProxyFieldTrial()) {
- // If DirectWrite is enabled for font rendering then open the font
- // cache section which is created by the browser and pass the handle to
- // the renderer process. This is needed because renderer processes on
- // Windows 8+ may be running in an AppContainer sandbox and hence their
- // kernel object namespace may be partitioned.
- std::string name(content::kFontCacheSharedSectionName);
- name.append(base::UintToString(base::GetCurrentProcId()));
-
- base::SharedMemory direct_write_font_cache_section;
- if (direct_write_font_cache_section.Open(name, true)) {
- void* shared_handle = policy->AddHandleToShare(
- direct_write_font_cache_section.handle().GetHandle());
- cmd_line->AppendSwitchASCII(
- switches::kFontCacheSharedHandle,
- base::UintToString(base::win::HandleToUint32(shared_handle)));
- }
- }
}
}
#endif
diff --git a/chromium/content/common/service_port_service.mojom b/chromium/content/common/service_port_service.mojom
deleted file mode 100644
index d5bbb58a497..00000000000
--- a/chromium/content/common/service_port_service.mojom
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 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.
-
-module content;
-
-enum ServicePortConnectResult {
- ACCEPT,
- REJECT
-};
-
-struct MojoTransferredMessagePort {
- int32 id;
- bool send_messages_as_values;
-};
-
-interface ServicePortService {
- SetClient(ServicePortServiceClient client);
-
- Connect(string target_url, string origin)
- => (ServicePortConnectResult result, int32 port_id);
-
- PostMessageToPort(int32 port_id, string message,
- array<MojoTransferredMessagePort> ports);
- ClosePort(int32 port_id);
-};
-
-interface ServicePortServiceClient {
- PostMessageToPort(int32 port_id, string message,
- array<MojoTransferredMessagePort> ports,
- array<int32> new_routing_ids);
-};
-
-interface ServicePortDispatcher {
- Connect(string target_url, string origin, int32 port_id)
- => (ServicePortConnectResult result, string name, string data);
-};
diff --git a/chromium/content/common/service_port_type_converters.cc b/chromium/content/common/service_port_type_converters.cc
deleted file mode 100644
index c07a946a972..00000000000
--- a/chromium/content/common/service_port_type_converters.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 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 "content/common/service_port_type_converters.h"
-
-namespace mojo {
-
-// static
-content::TransferredMessagePort
-TypeConverter<content::TransferredMessagePort,
- content::MojoTransferredMessagePortPtr>::
- Convert(const content::MojoTransferredMessagePortPtr& input) {
- content::TransferredMessagePort output;
- output.id = input->id;
- output.send_messages_as_values = input->send_messages_as_values;
- return output;
-}
-
-// static
-content::MojoTransferredMessagePortPtr
-TypeConverter<content::MojoTransferredMessagePortPtr,
- content::TransferredMessagePort>::
- Convert(const content::TransferredMessagePort& input) {
- content::MojoTransferredMessagePortPtr output(
- content::MojoTransferredMessagePort::New());
- output->id = input.id;
- output->send_messages_as_values = input.send_messages_as_values;
- return output;
-}
-
-} // namespace mojo
diff --git a/chromium/content/common/service_port_type_converters.h b/chromium/content/common/service_port_type_converters.h
deleted file mode 100644
index 70e01f9329c..00000000000
--- a/chromium/content/common/service_port_type_converters.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 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 CONTENT_COMMON_SERVICE_PORT_TYPE_CONVERTERS_H_
-#define CONTENT_COMMON_SERVICE_PORT_TYPE_CONVERTERS_H_
-
-#include "content/common/content_export.h"
-#include "content/common/service_port_service.mojom.h"
-#include "content/public/common/message_port_types.h"
-#include "mojo/public/cpp/bindings/type_converter.h"
-
-namespace mojo {
-
-template <>
-struct CONTENT_EXPORT TypeConverter<content::TransferredMessagePort,
- content::MojoTransferredMessagePortPtr> {
- static content::TransferredMessagePort Convert(
- const content::MojoTransferredMessagePortPtr& input);
-};
-
-template <>
-struct CONTENT_EXPORT TypeConverter<content::MojoTransferredMessagePortPtr,
- content::TransferredMessagePort> {
- static content::MojoTransferredMessagePortPtr Convert(
- const content::TransferredMessagePort& input);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_COMMON_SERVICE_PORT_TYPE_CONVERTERS_H_
diff --git a/chromium/content/common/service_worker/embedded_worker_messages.h b/chromium/content/common/service_worker/embedded_worker_messages.h
index fc9f02ea343..86fb48c8507 100644
--- a/chromium/content/common/service_worker/embedded_worker_messages.h
+++ b/chromium/content/common/service_worker/embedded_worker_messages.h
@@ -8,6 +8,7 @@
#include <string>
+#include "content/common/service_worker/embedded_worker_settings.h"
#include "content/public/common/web_preferences.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
@@ -19,6 +20,11 @@
#define IPC_MESSAGE_START EmbeddedWorkerMsgStart
+IPC_STRUCT_TRAITS_BEGIN(content::EmbeddedWorkerSettings)
+ IPC_STRUCT_TRAITS_MEMBER(v8_cache_options)
+ IPC_STRUCT_TRAITS_MEMBER(data_saver_enabled)
+IPC_STRUCT_TRAITS_END()
+
// Parameters structure for EmbeddedWorkerMsg_StartWorker.
IPC_STRUCT_BEGIN(EmbeddedWorkerMsg_StartWorker_Params)
IPC_STRUCT_MEMBER(int, embedded_worker_id)
@@ -26,8 +32,10 @@ IPC_STRUCT_BEGIN(EmbeddedWorkerMsg_StartWorker_Params)
IPC_STRUCT_MEMBER(GURL, scope)
IPC_STRUCT_MEMBER(GURL, script_url)
IPC_STRUCT_MEMBER(int, worker_devtools_agent_route_id)
+ IPC_STRUCT_MEMBER(bool, pause_after_download)
IPC_STRUCT_MEMBER(bool, wait_for_debugger)
- IPC_STRUCT_MEMBER(content::V8CacheOptions, v8_cache_options)
+ IPC_STRUCT_MEMBER(bool, is_installed)
+ IPC_STRUCT_MEMBER(content::EmbeddedWorkerSettings, settings)
IPC_STRUCT_END()
// Parameters structure for EmbeddedWorkerHostMsg_ReportConsoleMessage.
@@ -45,6 +53,11 @@ IPC_STRUCT_END()
IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StartWorker,
EmbeddedWorkerMsg_StartWorker_Params /* params */)
+// Browser -> Renderer message to resume a worker that has been started
+// with the pause_after_download option.
+IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_ResumeAfterDownload,
+ int /* embedded_worker_id */)
+
// Browser -> Renderer message to stop (terminate) the embedded worker.
IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StopWorker,
int /* embedded_worker_id */)
diff --git a/chromium/content/common/service_worker/embedded_worker_settings.h b/chromium/content/common/service_worker/embedded_worker_settings.h
new file mode 100644
index 00000000000..2014dae91c4
--- /dev/null
+++ b/chromium/content/common/service_worker/embedded_worker_settings.h
@@ -0,0 +1,19 @@
+// Copyright 2016 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 CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_SETTINGS_H_
+#define CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_SETTINGS_H_
+
+#include "content/public/common/web_preferences.h"
+
+namespace content {
+
+struct EmbeddedWorkerSettings {
+ content::V8CacheOptions v8_cache_options;
+ bool data_saver_enabled;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_SETTINGS_H_
diff --git a/chromium/content/common/service_worker/embedded_worker_setup.mojom b/chromium/content/common/service_worker/embedded_worker_setup.mojom
index 4a748541c1e..ad4583d1c64 100644
--- a/chromium/content/common/service_worker/embedded_worker_setup.mojom
+++ b/chromium/content/common/service_worker/embedded_worker_setup.mojom
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
-import "mojo/shell/public/interfaces/service_provider.mojom";
+import "mojo/shell/public/interfaces/interface_provider.mojom";
interface EmbeddedWorkerSetup {
- ExchangeServiceProviders(int32 thread_id,
- mojo.ServiceProvider& services,
- mojo.ServiceProvider exposed_services);
+ ExchangeInterfaceProviders(
+ int32 thread_id,
+ mojo.shell.mojom.InterfaceProvider& remote_interfaces,
+ mojo.shell.mojom.InterfaceProvider local_interfaces);
};
diff --git a/chromium/content/common/service_worker/service_worker_client_info.cc b/chromium/content/common/service_worker/service_worker_client_info.cc
index c864369c039..a412fa0b7de 100644
--- a/chromium/content/common/service_worker/service_worker_client_info.cc
+++ b/chromium/content/common/service_worker/service_worker_client_info.cc
@@ -10,25 +10,32 @@
namespace content {
ServiceWorkerClientInfo::ServiceWorkerClientInfo()
- : page_visibility_state(blink::WebPageVisibilityStateLast),
- is_focused(false),
- frame_type(REQUEST_CONTEXT_FRAME_TYPE_LAST),
- client_type(blink::WebServiceWorkerClientTypeLast),
- last_focus_time(base::TimeTicks()) {}
+ : ServiceWorkerClientInfo(std::string(),
+ blink::WebPageVisibilityStateLast,
+ false,
+ GURL(),
+ REQUEST_CONTEXT_FRAME_TYPE_LAST,
+ base::TimeTicks(),
+ blink::WebServiceWorkerClientTypeLast) {}
ServiceWorkerClientInfo::ServiceWorkerClientInfo(
+ const std::string& client_uuid,
blink::WebPageVisibilityState page_visibility_state,
bool is_focused,
const GURL& url,
RequestContextFrameType frame_type,
base::TimeTicks last_focus_time,
blink::WebServiceWorkerClientType client_type)
- : page_visibility_state(page_visibility_state),
+ : client_uuid(client_uuid),
+ page_visibility_state(page_visibility_state),
is_focused(is_focused),
url(url),
frame_type(frame_type),
- client_type(client_type),
- last_focus_time(last_focus_time) {}
+ last_focus_time(last_focus_time),
+ client_type(client_type) {}
+
+ServiceWorkerClientInfo::ServiceWorkerClientInfo(
+ const ServiceWorkerClientInfo& other) = default;
bool ServiceWorkerClientInfo::IsEmpty() const {
return page_visibility_state == blink::WebPageVisibilityStateLast &&
diff --git a/chromium/content/common/service_worker/service_worker_client_info.h b/chromium/content/common/service_worker/service_worker_client_info.h
index 1c81fe34816..93bfdf447a2 100644
--- a/chromium/content/common/service_worker/service_worker_client_info.h
+++ b/chromium/content/common/service_worker/service_worker_client_info.h
@@ -20,12 +20,14 @@ namespace content {
// constructor to fill the properties.
struct ServiceWorkerClientInfo {
ServiceWorkerClientInfo();
- ServiceWorkerClientInfo(blink::WebPageVisibilityState page_visibility_state,
+ ServiceWorkerClientInfo(const std::string& client_uuid,
+ blink::WebPageVisibilityState page_visibility_state,
bool is_focused,
const GURL& url,
RequestContextFrameType frame_type,
base::TimeTicks last_focus_time,
blink::WebServiceWorkerClientType client_type);
+ ServiceWorkerClientInfo(const ServiceWorkerClientInfo& other);
// Returns whether the instance is empty.
bool IsEmpty() const;
@@ -39,8 +41,8 @@ struct ServiceWorkerClientInfo {
bool is_focused;
GURL url;
RequestContextFrameType frame_type;
- blink::WebServiceWorkerClientType client_type;
base::TimeTicks last_focus_time;
+ blink::WebServiceWorkerClientType client_type;
};
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_messages.h b/chromium/content/common/service_worker/service_worker_messages.h
index 8ba0e58e7f0..41698cff41e 100644
--- a/chromium/content/common/service_worker/service_worker_messages.h
+++ b/chromium/content/common/service_worker/service_worker_messages.h
@@ -14,8 +14,8 @@
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/message_port_types.h"
-#include "content/public/common/navigator_connect_client.h"
#include "content/public/common/platform_notification_data.h"
+#include "content/public/common/push_event_payload.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
@@ -23,6 +23,7 @@
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerEventResult.h"
#include "url/gurl.h"
+#include "url/origin.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
@@ -50,6 +51,14 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebServiceWorkerClientType,
IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerProviderType,
content::SERVICE_WORKER_PROVIDER_TYPE_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchType,
+ content::ServiceWorkerFetchType::LAST)
+
+IPC_STRUCT_TRAITS_BEGIN(content::ExtendableMessageEventSource)
+ IPC_STRUCT_TRAITS_MEMBER(client_info)
+ IPC_STRUCT_TRAITS_MEMBER(service_worker_info)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerFetchRequest)
IPC_STRUCT_TRAITS_MEMBER(mode)
IPC_STRUCT_TRAITS_MEMBER(is_main_resource_load)
@@ -65,6 +74,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerFetchRequest)
IPC_STRUCT_TRAITS_MEMBER(redirect_mode)
IPC_STRUCT_TRAITS_MEMBER(client_id)
IPC_STRUCT_TRAITS_MEMBER(is_reload)
+ IPC_STRUCT_TRAITS_MEMBER(fetch_type)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchEventResult,
@@ -80,6 +90,9 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse)
IPC_STRUCT_TRAITS_MEMBER(blob_size)
IPC_STRUCT_TRAITS_MEMBER(stream_url)
IPC_STRUCT_TRAITS_MEMBER(error)
+ IPC_STRUCT_TRAITS_MEMBER(response_time)
+ IPC_STRUCT_TRAITS_MEMBER(is_in_cache_storage)
+ IPC_STRUCT_TRAITS_MEMBER(cache_storage_cache_name)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerObjectInfo)
@@ -115,6 +128,14 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerClientQueryOptions)
IPC_STRUCT_TRAITS_MEMBER(include_uncontrolled)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_BEGIN(ServiceWorkerMsg_ExtendableMessageEvent_Params)
+ IPC_STRUCT_MEMBER(base::string16, message)
+ IPC_STRUCT_MEMBER(url::Origin, source_origin)
+ IPC_STRUCT_MEMBER(std::vector<content::TransferredMessagePort>, message_ports)
+ IPC_STRUCT_MEMBER(std::vector<int>, new_routing_ids)
+ IPC_STRUCT_MEMBER(content::ExtendableMessageEventSource, source)
+IPC_STRUCT_END()
+
IPC_STRUCT_BEGIN(ServiceWorkerMsg_MessageToDocument_Params)
IPC_STRUCT_MEMBER(int, thread_id)
IPC_STRUCT_MEMBER(int, provider_id)
@@ -127,10 +148,9 @@ IPC_STRUCT_END()
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebGeofencingEventType,
blink::WebGeofencingEventTypeLast)
-IPC_STRUCT_TRAITS_BEGIN(content::NavigatorConnectClient)
- IPC_STRUCT_TRAITS_MEMBER(target_url)
- IPC_STRUCT_TRAITS_MEMBER(origin)
- IPC_STRUCT_TRAITS_MEMBER(message_port_id)
+IPC_STRUCT_TRAITS_BEGIN(content::PushEventPayload)
+ IPC_STRUCT_TRAITS_MEMBER(data)
+ IPC_STRUCT_TRAITS_MEMBER(is_null)
IPC_STRUCT_TRAITS_END()
//---------------------------------------------------------------------------
@@ -171,10 +191,21 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerHostMsg_GetRegistrationForReady,
int /* request_id */,
int /* provider_id */)
-// Sends a 'message' event to a service worker (renderer->browser).
-IPC_MESSAGE_CONTROL3(
+// Sends ExtendableMessageEvent to a service worker (renderer->browser).
+IPC_MESSAGE_CONTROL5(
ServiceWorkerHostMsg_PostMessageToWorker,
int /* handle_id */,
+ int /* provider_id */,
+ base::string16 /* message */,
+ url::Origin /* source_origin */,
+ std::vector<content::TransferredMessagePort> /* sent_message_ports */)
+
+// Sends MessageEvent to a service worker (renderer->browser).
+// TODO(nhiroki): Remove this after ExtendableMessageEvent is enabled by
+// default (crbug.com/543198).
+IPC_MESSAGE_CONTROL3(
+ ServiceWorkerHostMsg_DeprecatedPostMessageToWorker,
+ int /* handle_id */,
base::string16 /* message */,
std::vector<content::TransferredMessagePort> /* sent_message_ports */)
@@ -231,12 +262,19 @@ IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_InstallEventFinished,
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_ActivateEventFinished,
int /* request_id */,
blink::WebServiceWorkerEventResult)
+IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_ExtendableMessageEventFinished,
+ int /* request_id */,
+ blink::WebServiceWorkerEventResult)
IPC_MESSAGE_ROUTED3(ServiceWorkerHostMsg_FetchEventFinished,
int /* request_id */,
content::ServiceWorkerFetchEventResult,
content::ServiceWorkerResponse)
-IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_NotificationClickEventFinished,
- int /* request_id */)
+IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_NotificationClickEventFinished,
+ int /* request_id */,
+ blink::WebServiceWorkerEventResult)
+IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_NotificationCloseEventFinished,
+ int /* request_id */,
+ blink::WebServiceWorkerEventResult)
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_PushEventFinished,
int /* request_id */,
blink::WebServiceWorkerEventResult)
@@ -248,12 +286,17 @@ IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_GeofencingEventFinished,
// Routed to the target ServiceWorkerVersion.
IPC_MESSAGE_ROUTED0(ServiceWorkerHostMsg_Pong)
+// Asks the browser to retrieve client of the sender ServiceWorker.
+IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_GetClient,
+ int /* request_id */,
+ std::string /* client_uuid */)
+
// Asks the browser to retrieve clients of the sender ServiceWorker.
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_GetClients,
int /* request_id */,
content::ServiceWorkerClientQueryOptions)
-// Sends a 'message' event to a client (renderer->browser).
+// Sends MessageEvent to a client (renderer->browser).
IPC_MESSAGE_ROUTED3(
ServiceWorkerHostMsg_PostMessageToClient,
std::string /* uuid */,
@@ -297,8 +340,9 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_ClaimClients,
// Informs the browser of new foreign fetch subscopes this worker wants to
// handle. Should only be sent while an install event is being handled.
-IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_RegisterForeignFetchScopes,
- std::vector<GURL> /* sub_scopes */)
+IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_RegisterForeignFetchScopes,
+ std::vector<GURL> /* sub_scopes */,
+ std::vector<url::Origin> /* origins */)
//---------------------------------------------------------------------------
// Messages sent from the browser to the child process.
@@ -425,7 +469,7 @@ IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_SetControllerServiceWorker,
content::ServiceWorkerObjectInfo,
bool /* should_notify_controllerchange */)
-// Sends a 'message' event to a client document (browser->renderer).
+// Sends MessageEvent to a client document (browser->renderer).
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_MessageToDocument,
ServiceWorkerMsg_MessageToDocument_Params)
@@ -434,6 +478,9 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_InstallEvent,
int /* request_id */)
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_ActivateEvent,
int /* request_id */)
+IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_ExtendableMessageEvent,
+ int /* request_id */,
+ ServiceWorkerMsg_ExtendableMessageEvent_Params)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FetchEvent,
int /* request_id */,
content::ServiceWorkerFetchRequest)
@@ -442,25 +489,27 @@ IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_NotificationClickEvent,
int64_t /* persistent_notification_id */,
content::PlatformNotificationData /* notification_data */,
int /* action_index */)
+IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_NotificationCloseEvent,
+ int /* request_id */,
+ int64_t /* persistent_notification_id */,
+ content::PlatformNotificationData /* notification_data */)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_PushEvent,
int /* request_id */,
- std::string /* data */)
+ content::PushEventPayload /* data */)
IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_GeofencingEvent,
int /* request_id */,
blink::WebGeofencingEventType /* event_type */,
std::string /* region_id */,
blink::WebCircularGeofencingRegion /* region */)
+
+// TODO(nhiroki): Remove this after ExtendableMessageEvent is enabled by
+// default (crbug.com/543198).
IPC_MESSAGE_CONTROL3(
ServiceWorkerMsg_MessageToWorker,
base::string16 /* message */,
std::vector<content::TransferredMessagePort> /* sent_message_ports */,
std::vector<int> /* new_routing_ids */)
-IPC_MESSAGE_CONTROL4(
- ServiceWorkerMsg_CrossOriginMessageToWorker,
- content::NavigatorConnectClient /* client */,
- base::string16 /* message */,
- std::vector<content::TransferredMessagePort> /* sent_message_ports */,
- std::vector<int> /* new_routing_ids */)
+
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_DidSkipWaiting,
int /* request_id */)
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_DidClaimClients,
@@ -473,6 +522,11 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ClaimClientsError,
// Sent via EmbeddedWorker to Ping the worker, expecting a Pong in response.
IPC_MESSAGE_CONTROL0(ServiceWorkerMsg_Ping)
+// Sent via EmbeddedWorker as a response of GetClient.
+IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidGetClient,
+ int /* request_id */,
+ content::ServiceWorkerClientInfo)
+
// Sent via EmbeddedWorker as a response of GetClients.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidGetClients,
int /* request_id */,
diff --git a/chromium/content/common/service_worker/service_worker_status_code.h b/chromium/content/common/service_worker/service_worker_status_code.h
index 3dff585c4b2..24be8167310 100644
--- a/chromium/content/common/service_worker/service_worker_status_code.h
+++ b/chromium/content/common/service_worker/service_worker_status_code.h
@@ -10,69 +10,74 @@
namespace content {
// Generic service worker operation statuses.
-// This enum is used in UMA histograms, so don't change the order or remove
-// entries.
+// This enum is used in UMA histograms. Append-only.
enum ServiceWorkerStatusCode {
// Operation succeeded.
- SERVICE_WORKER_OK,
+ SERVICE_WORKER_OK = 0,
// Generic operation error (more specific error code should be used in
// general).
- SERVICE_WORKER_ERROR_FAILED,
+ SERVICE_WORKER_ERROR_FAILED = 1,
// Operation was aborted (e.g. due to context or child process shutdown).
- SERVICE_WORKER_ERROR_ABORT,
+ SERVICE_WORKER_ERROR_ABORT = 2,
// Starting a new service worker script context failed.
- SERVICE_WORKER_ERROR_START_WORKER_FAILED,
+ SERVICE_WORKER_ERROR_START_WORKER_FAILED = 3,
// Could not find a renderer process to run a service worker.
- SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND,
+ SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND = 4,
// Generic error code to indicate the specified item is not found.
- SERVICE_WORKER_ERROR_NOT_FOUND,
+ SERVICE_WORKER_ERROR_NOT_FOUND = 5,
// Generic error code to indicate the specified item already exists.
- SERVICE_WORKER_ERROR_EXISTS,
+ SERVICE_WORKER_ERROR_EXISTS = 6,
// Install event handling failed.
- SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED,
+ SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED = 7,
// Activate event handling failed.
- SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED,
+ SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED = 8,
// Sending an IPC to the worker failed (often due to child process is
// terminated).
- SERVICE_WORKER_ERROR_IPC_FAILED,
+ SERVICE_WORKER_ERROR_IPC_FAILED = 9,
// Operation is failed by network issue.
- SERVICE_WORKER_ERROR_NETWORK,
+ SERVICE_WORKER_ERROR_NETWORK = 10,
// Operation is failed by security issue.
- SERVICE_WORKER_ERROR_SECURITY,
+ SERVICE_WORKER_ERROR_SECURITY = 11,
// Event handling failed (event.waitUntil Promise rejected).
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+ SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED = 12,
// An error triggered by invalid worker state.
- SERVICE_WORKER_ERROR_STATE,
+ SERVICE_WORKER_ERROR_STATE = 13,
// The Service Worker took too long to finish a task.
- SERVICE_WORKER_ERROR_TIMEOUT,
+ SERVICE_WORKER_ERROR_TIMEOUT = 14,
// An error occurred during initial script evaluation.
- SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED,
+ SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED = 15,
// Generic error to indicate failure to read/write the disk cache.
- SERVICE_WORKER_ERROR_DISK_CACHE,
+ SERVICE_WORKER_ERROR_DISK_CACHE = 16,
// The worker is in REDUNDANT state.
- SERVICE_WORKER_ERROR_REDUNDANT,
+ SERVICE_WORKER_ERROR_REDUNDANT = 17,
- // The worker was disallowed.
- SERVICE_WORKER_ERROR_DISALLOWED,
+ // The worker was disallowed (by ContentClient: e.g., due to
+ // browser settings).
+ SERVICE_WORKER_ERROR_DISALLOWED = 18,
- SERVICE_WORKER_ERROR_MAX_VALUE
+ // Obsolete.
+ // SERVICE_WORKER_ERROR_DISABLED_WORKER = 19,
+
+ // Add new status codes here.
+
+ SERVICE_WORKER_ERROR_MAX_VALUE = 20
};
CONTENT_EXPORT const char* ServiceWorkerStatusToString(
diff --git a/chromium/content/common/service_worker/service_worker_type_converters.cc b/chromium/content/common/service_worker/service_worker_type_converters.cc
index 735f529a932..b752e142772 100644
--- a/chromium/content/common/service_worker/service_worker_type_converters.cc
+++ b/chromium/content/common/service_worker/service_worker_type_converters.cc
@@ -12,14 +12,14 @@ namespace mojo {
// static cast.
content::ServiceWorkerStatusCode
TypeConverter<content::ServiceWorkerStatusCode,
- content::ServiceWorkerEventStatus>::
- Convert(content::ServiceWorkerEventStatus status) {
+ content::mojom::ServiceWorkerEventStatus>::
+ Convert(content::mojom::ServiceWorkerEventStatus status) {
content::ServiceWorkerStatusCode status_code;
- if (status == content::SERVICE_WORKER_EVENT_STATUS_COMPLETED) {
+ if (status == content::mojom::ServiceWorkerEventStatus::COMPLETED) {
status_code = content::SERVICE_WORKER_OK;
- } else if (status == content::SERVICE_WORKER_EVENT_STATUS_REJECTED) {
+ } else if (status == content::mojom::ServiceWorkerEventStatus::REJECTED) {
status_code = content::SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED;
- } else if (status == content::SERVICE_WORKER_EVENT_STATUS_ABORTED) {
+ } else if (status == content::mojom::ServiceWorkerEventStatus::ABORTED) {
status_code = content::SERVICE_WORKER_ERROR_ABORT;
} else {
// We received an unexpected value back. This can theoretically happen as
diff --git a/chromium/content/common/service_worker/service_worker_type_converters.h b/chromium/content/common/service_worker/service_worker_type_converters.h
index 42606e34dc9..4c43fdaf8c0 100644
--- a/chromium/content/common/service_worker/service_worker_type_converters.h
+++ b/chromium/content/common/service_worker/service_worker_type_converters.h
@@ -12,9 +12,9 @@ namespace mojo {
template <>
struct CONTENT_EXPORT TypeConverter<content::ServiceWorkerStatusCode,
- content::ServiceWorkerEventStatus> {
+ content::mojom::ServiceWorkerEventStatus> {
static content::ServiceWorkerStatusCode Convert(
- content::ServiceWorkerEventStatus status);
+ content::mojom::ServiceWorkerEventStatus status);
};
} // namespace
diff --git a/chromium/content/common/service_worker/service_worker_types.cc b/chromium/content/common/service_worker/service_worker_types.cc
index e9ff0b96319..a320c29725a 100644
--- a/chromium/content/common/service_worker/service_worker_types.cc
+++ b/chromium/content/common/service_worker/service_worker_types.cc
@@ -27,7 +27,8 @@ ServiceWorkerFetchRequest::ServiceWorkerFetchRequest()
blob_size(0),
credentials_mode(FETCH_CREDENTIALS_MODE_OMIT),
redirect_mode(FetchRedirectMode::FOLLOW_MODE),
- is_reload(false) {}
+ is_reload(false),
+ fetch_type(ServiceWorkerFetchType::FETCH) {}
ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
const GURL& url,
@@ -46,7 +47,11 @@ ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
referrer(referrer),
credentials_mode(FETCH_CREDENTIALS_MODE_OMIT),
redirect_mode(FetchRedirectMode::FOLLOW_MODE),
- is_reload(is_reload) {}
+ is_reload(is_reload),
+ fetch_type(ServiceWorkerFetchType::FETCH) {}
+
+ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
+ const ServiceWorkerFetchRequest& other) = default;
ServiceWorkerFetchRequest::~ServiceWorkerFetchRequest() {}
@@ -54,8 +59,7 @@ ServiceWorkerResponse::ServiceWorkerResponse()
: status_code(0),
response_type(blink::WebServiceWorkerResponseTypeOpaque),
blob_size(0),
- error(blink::WebServiceWorkerResponseErrorUnknown) {
-}
+ error(blink::WebServiceWorkerResponseErrorUnknown) {}
ServiceWorkerResponse::ServiceWorkerResponse(
const GURL& url,
@@ -66,7 +70,10 @@ ServiceWorkerResponse::ServiceWorkerResponse(
const std::string& blob_uuid,
uint64_t blob_size,
const GURL& stream_url,
- blink::WebServiceWorkerResponseError error)
+ blink::WebServiceWorkerResponseError error,
+ base::Time response_time,
+ bool is_in_cache_storage,
+ const std::string& cache_storage_cache_name)
: url(url),
status_code(status_code),
status_text(status_text),
@@ -75,7 +82,13 @@ ServiceWorkerResponse::ServiceWorkerResponse(
blob_uuid(blob_uuid),
blob_size(blob_size),
stream_url(stream_url),
- error(error) {}
+ error(error),
+ response_time(response_time),
+ is_in_cache_storage(is_in_cache_storage),
+ cache_storage_cache_name(cache_storage_cache_name) {}
+
+ServiceWorkerResponse::ServiceWorkerResponse(
+ const ServiceWorkerResponse& other) = default;
ServiceWorkerResponse::~ServiceWorkerResponse() {}
@@ -84,6 +97,11 @@ ServiceWorkerObjectInfo::ServiceWorkerObjectInfo()
state(blink::WebServiceWorkerStateUnknown),
version_id(kInvalidServiceWorkerVersionId) {}
+bool ServiceWorkerObjectInfo::IsValid() const {
+ return handle_id != kInvalidServiceWorkerHandleId &&
+ version_id != kInvalidServiceWorkerVersionId;
+}
+
ServiceWorkerRegistrationObjectInfo::ServiceWorkerRegistrationObjectInfo()
: handle_id(kInvalidServiceWorkerRegistrationHandleId),
registration_id(kInvalidServiceWorkerRegistrationId) {
@@ -94,4 +112,14 @@ ServiceWorkerClientQueryOptions::ServiceWorkerClientQueryOptions()
include_uncontrolled(false) {
}
+ExtendableMessageEventSource::ExtendableMessageEventSource() {}
+
+ExtendableMessageEventSource::ExtendableMessageEventSource(
+ const ServiceWorkerClientInfo& client_info)
+ : client_info(client_info) {}
+
+ExtendableMessageEventSource::ExtendableMessageEventSource(
+ const ServiceWorkerObjectInfo& service_worker_info)
+ : service_worker_info(service_worker_info) {}
+
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_types.h b/chromium/content/common/service_worker/service_worker_types.h
index d3a9f8f2a99..81f7d4f7d50 100644
--- a/chromium/content/common/service_worker/service_worker_types.h
+++ b/chromium/content/common/service_worker/service_worker_types.h
@@ -11,7 +11,9 @@
#include <string>
#include "base/strings/string_util.h"
+#include "base/time/time.h"
#include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_client_info.h"
#include "content/public/common/referrer.h"
#include "content/public/common/request_context_frame_type.h"
#include "content/public/common/request_context_type.h"
@@ -87,7 +89,8 @@ enum FetchCredentialsMode {
FETCH_CREDENTIALS_MODE_OMIT,
FETCH_CREDENTIALS_MODE_SAME_ORIGIN,
FETCH_CREDENTIALS_MODE_INCLUDE,
- FETCH_CREDENTIALS_MODE_LAST = FETCH_CREDENTIALS_MODE_INCLUDE
+ FETCH_CREDENTIALS_MODE_PASSWORD,
+ FETCH_CREDENTIALS_MODE_LAST = FETCH_CREDENTIALS_MODE_PASSWORD
};
enum class FetchRedirectMode {
@@ -106,6 +109,12 @@ enum ServiceWorkerFetchEventResult {
SERVICE_WORKER_FETCH_EVENT_LAST = SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE
};
+enum class ServiceWorkerFetchType {
+ FETCH,
+ FOREIGN_FETCH,
+ LAST = FOREIGN_FETCH
+};
+
struct ServiceWorkerCaseInsensitiveCompare {
bool operator()(const std::string& lhs, const std::string& rhs) const {
return base::CompareCaseInsensitiveASCII(lhs, rhs) < 0;
@@ -123,6 +132,7 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
const ServiceWorkerHeaderMap& headers,
const Referrer& referrer,
bool is_reload);
+ ServiceWorkerFetchRequest(const ServiceWorkerFetchRequest& other);
~ServiceWorkerFetchRequest();
FetchRequestMode mode;
@@ -139,6 +149,7 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
FetchRedirectMode redirect_mode;
std::string client_id;
bool is_reload;
+ ServiceWorkerFetchType fetch_type;
};
// Represents a response to a fetch.
@@ -152,7 +163,11 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
const std::string& blob_uuid,
uint64_t blob_size,
const GURL& stream_url,
- blink::WebServiceWorkerResponseError error);
+ blink::WebServiceWorkerResponseError error,
+ base::Time response_time,
+ bool is_in_cache_storage,
+ const std::string& cache_storage_cache_name);
+ ServiceWorkerResponse(const ServiceWorkerResponse& other);
~ServiceWorkerResponse();
GURL url;
@@ -164,11 +179,19 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
uint64_t blob_size;
GURL stream_url;
blink::WebServiceWorkerResponseError error;
+ base::Time response_time;
+ bool is_in_cache_storage = false;
+ std::string cache_storage_cache_name;
};
// Represents initialization info for a WebServiceWorker object.
struct CONTENT_EXPORT ServiceWorkerObjectInfo {
ServiceWorkerObjectInfo();
+
+ // Returns whether the instance is valid. A valid instance has valid
+ // |handle_id| and |version_id|.
+ bool IsValid() const;
+
int handle_id;
GURL url;
blink::WebServiceWorkerState state;
@@ -218,6 +241,18 @@ struct ServiceWorkerClientQueryOptions {
bool include_uncontrolled;
};
+struct ExtendableMessageEventSource {
+ ExtendableMessageEventSource();
+ explicit ExtendableMessageEventSource(
+ const ServiceWorkerClientInfo& client_info);
+ explicit ExtendableMessageEventSource(
+ const ServiceWorkerObjectInfo& service_worker_info);
+
+ // Exactly one of these infos should be valid.
+ ServiceWorkerClientInfo client_info;
+ ServiceWorkerObjectInfo service_worker_info;
+};
+
} // namespace content
#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_H_
diff --git a/chromium/content/common/service_worker/service_worker_utils.cc b/chromium/content/common/service_worker/service_worker_utils.cc
index 62f197528f1..3a4971fc4ec 100644
--- a/chromium/content/common/service_worker/service_worker_utils.cc
+++ b/chromium/content/common/service_worker/service_worker_utils.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
+#include "content/public/common/origin_util.h"
namespace content {
@@ -30,12 +31,16 @@ bool PathContainsDisallowedCharacter(const GURL& url) {
return false;
}
+bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) {
+ return url_a.GetOrigin() == url_b.GetOrigin() &&
+ url_a.GetOrigin() == url_c.GetOrigin();
+}
+
} // namespace
// static
bool ServiceWorkerUtils::ScopeMatches(const GURL& scope, const GURL& url) {
DCHECK(!scope.has_ref());
- DCHECK(!url.has_ref());
return base::StartsWith(url.spec(), scope.spec(),
base::CompareCase::SENSITIVE);
}
@@ -104,6 +109,19 @@ bool ServiceWorkerUtils::ContainsDisallowedCharacter(
return false;
}
+// static
+bool ServiceWorkerUtils::CanRegisterServiceWorker(const GURL& context_url,
+ const GURL& pattern,
+ const GURL& script_url) {
+ DCHECK(context_url.is_valid());
+ DCHECK(pattern.is_valid());
+ DCHECK(script_url.is_valid());
+ return AllOriginsMatch(context_url, pattern, script_url) &&
+ OriginCanAccessServiceWorkers(context_url) &&
+ OriginCanAccessServiceWorkers(pattern) &&
+ OriginCanAccessServiceWorkers(script_url);
+}
+
bool LongestScopeMatcher::MatchLongest(const GURL& scope) {
if (!ServiceWorkerUtils::ScopeMatches(scope, url_))
return false;
diff --git a/chromium/content/common/service_worker/service_worker_utils.h b/chromium/content/common/service_worker/service_worker_utils.h
index 8538b5ea304..5be59c0aa80 100644
--- a/chromium/content/common/service_worker/service_worker_utils.h
+++ b/chromium/content/common/service_worker/service_worker_utils.h
@@ -40,6 +40,10 @@ class ServiceWorkerUtils {
const GURL& script_url,
std::string* error_message);
+ static bool CanRegisterServiceWorker(const GURL& context_url,
+ const GURL& pattern,
+ const GURL& script_url);
+
// PlzNavigate
// Returns true if the |provider_id| was assigned by the browser process.
static bool IsBrowserAssignedProviderId(int provider_id) {
diff --git a/chromium/content/common/service_worker/service_worker_utils_unittest.cc b/chromium/content/common/service_worker/service_worker_utils_unittest.cc
index f8ab571682d..393c36ce158 100644
--- a/chromium/content/common/service_worker/service_worker_utils_unittest.cc
+++ b/chromium/content/common/service_worker/service_worker_utils_unittest.cc
@@ -38,6 +38,8 @@ TEST(ServiceWorkerUtilsTest, ScopeMatches) {
ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
GURL("http://www.example.com/"),
GURL("https://www.example.com/page.html")));
+ ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
+ GURL("http://www.example.com/"), GURL("http://www.example.com/#a")));
ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/"),
GURL("http://www.foo.com/")));
diff --git a/chromium/content/common/site_isolation_policy.cc b/chromium/content/common/site_isolation_policy.cc
index 60288700ca7..b25741b3b39 100644
--- a/chromium/content/common/site_isolation_policy.cc
+++ b/chromium/content/common/site_isolation_policy.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "content/public/common/browser_plugin_guest_mode.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
@@ -14,9 +15,10 @@ namespace content {
// static
bool SiteIsolationPolicy::AreCrossProcessFramesPossible() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSitePerProcess) ||
- GetContentClient()->IsSupplementarySiteIsolationModeEnabled();
+ return UseDedicatedProcessesForAllSites() ||
+ IsTopDocumentIsolationEnabled() ||
+ GetContentClient()->IsSupplementarySiteIsolationModeEnabled() ||
+ BrowserPluginGuestMode::UseCrossProcessFramesForGuests();
}
// static
@@ -26,6 +28,16 @@ bool SiteIsolationPolicy::UseDedicatedProcessesForAllSites() {
}
// static
+bool SiteIsolationPolicy::IsTopDocumentIsolationEnabled() {
+ // --site-per-process trumps --top-document-isolation.
+ if (UseDedicatedProcessesForAllSites())
+ return false;
+
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kTopDocumentIsolation);
+}
+
+// static
bool SiteIsolationPolicy::UseSubframeNavigationEntries() {
// Enable the new navigation history behavior if any manner of site isolation
// is active.
@@ -33,9 +45,4 @@ bool SiteIsolationPolicy::UseSubframeNavigationEntries() {
return AreCrossProcessFramesPossible() || IsBrowserSideNavigationEnabled();
}
-// static
-bool SiteIsolationPolicy::IsSwappedOutStateForbidden() {
- return true;
-}
-
} // namespace content
diff --git a/chromium/content/common/site_isolation_policy.h b/chromium/content/common/site_isolation_policy.h
index 69b6c5e4cf4..c6d6e6132aa 100644
--- a/chromium/content/common/site_isolation_policy.h
+++ b/chromium/content/common/site_isolation_policy.h
@@ -37,23 +37,16 @@ class CONTENT_EXPORT SiteIsolationPolicy {
// Returns true if every site should be placed in a dedicated process.
static bool UseDedicatedProcessesForAllSites();
+ // Returns true if third-party subframes of a page should be kept in a
+ // different process from the main frame.
+ static bool IsTopDocumentIsolationEnabled();
+
// Returns true if navigation and history code should maintain per-frame
// navigation entries. This is an in-progress feature related to site
// isolation, so the return value is currently tied to --site-per-process.
// TODO(creis, avi): Make this the default, and eliminate this.
static bool UseSubframeNavigationEntries();
- // Returns true if we are currently in a mode where the swapped out state
- // should not be used. Currently (as an implementation strategy) swapped out
- // is forbidden under --site-per-process, but our goal is to eliminate the
- // mode entirely. In code that deals with the swapped out state, prefer calls
- // to this function over consulting the switches directly. It will be easier
- // to grep, and easier to rip out.
- //
- // TODO(nasko): When swappedout:// is eliminated entirely, this function
- // should be removed and its callers cleaned up.
- static bool IsSwappedOutStateForbidden();
-
private:
SiteIsolationPolicy(); // Not instantiable.
diff --git a/chromium/content/common/storage_partition_service.mojom b/chromium/content/common/storage_partition_service.mojom
new file mode 100644
index 00000000000..3338658618d
--- /dev/null
+++ b/chromium/content/common/storage_partition_service.mojom
@@ -0,0 +1,15 @@
+// Copyright 2016 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.
+
+module content.mojom;
+
+import "content/common/leveldb_wrapper.mojom";
+import "url/mojo/origin.mojom";
+
+// Returns services related to the current storage partition.
+interface StoragePartitionService {
+ OpenLocalStorage(url.mojom.Origin origin,
+ LevelDBObserver observer,
+ LevelDBWrapper& database);
+};
diff --git a/chromium/content/common/swapped_out_messages.cc b/chromium/content/common/swapped_out_messages.cc
index 7980014711d..718dd08e49a 100644
--- a/chromium/content/common/swapped_out_messages.cc
+++ b/chromium/content/common/swapped_out_messages.cc
@@ -9,7 +9,6 @@
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_client.h"
-#include "content/shell/common/shell_messages.h"
namespace content {
@@ -40,8 +39,6 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) {
// Frame detach must occur after the RenderView has swapped out.
case FrameHostMsg_Detach::ID:
case FrameHostMsg_DomOperationResponse::ID:
- case FrameHostMsg_CompositorFrameSwappedACK::ID:
- case FrameHostMsg_ReclaimCompositorResources::ID:
// Input events propagate from parent to child.
case FrameHostMsg_ForwardInputEvent::ID:
case FrameHostMsg_InitializeChildFrame::ID:
@@ -50,8 +47,8 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) {
case FrameHostMsg_DidAssignPageId::ID:
// A swapped-out frame's opener might be updated with window.open.
case FrameHostMsg_DidChangeOpener::ID:
- // Used in layout tests; handled in BlinkTestController.
- case ShellViewHostMsg_PrintMessage::ID:
+ // For handling pop-ups from cross-site frames.
+ case ViewHostMsg_CreateWidget::ID:
return true;
default:
break;
diff --git a/chromium/content/common/text_input_client_messages.h b/chromium/content/common/text_input_client_messages.h
index 70da1d8916e..f66196cc6c5 100644
--- a/chromium/content/common/text_input_client_messages.h
+++ b/chromium/content/common/text_input_client_messages.h
@@ -48,7 +48,7 @@ IPC_MESSAGE_ROUTED1(TextInputClientMsg_StringAtPoint, gfx::Point)
// Reply message for TextInputClientMsg_CharacterIndexForPoint.
IPC_MESSAGE_ROUTED1(TextInputClientReplyMsg_GotCharacterIndexForPoint,
- size_t /* character index */)
+ uint32_t /* character index */)
// Reply message for TextInputClientMsg_FirstRectForCharacterRange.
IPC_MESSAGE_ROUTED1(TextInputClientReplyMsg_GotFirstRectForRange,
diff --git a/chromium/content/common/url_schemes.cc b/chromium/content/common/url_schemes.cc
index 6d4c58c699f..c985e854ae1 100644
--- a/chromium/content/common/url_schemes.cc
+++ b/chromium/content/common/url_schemes.cc
@@ -18,35 +18,37 @@
namespace {
-void AddStandardSchemeHelper(const url::SchemeWithType& scheme) {
- url::AddStandardScheme(scheme.scheme, scheme.type);
-}
-
} // namespace
namespace content {
-void RegisterContentSchemes(bool lock_standard_schemes) {
+void RegisterContentSchemes(bool lock_schemes) {
std::vector<url::SchemeWithType> additional_standard_schemes;
+ std::vector<url::SchemeWithType> additional_referrer_schemes;
std::vector<std::string> additional_savable_schemes;
+
GetContentClient()->AddAdditionalSchemes(&additional_standard_schemes,
+ &additional_referrer_schemes,
&additional_savable_schemes);
url::AddStandardScheme(kChromeDevToolsScheme, url::SCHEME_WITHOUT_PORT);
url::AddStandardScheme(kChromeUIScheme, url::SCHEME_WITHOUT_PORT);
url::AddStandardScheme(kGuestScheme, url::SCHEME_WITHOUT_PORT);
url::AddStandardScheme(kMetadataScheme, url::SCHEME_WITHOUT_AUTHORITY);
- std::for_each(additional_standard_schemes.begin(),
- additional_standard_schemes.end(),
- AddStandardSchemeHelper);
-
- // Prevent future modification of the standard schemes list. This is to
- // prevent accidental creation of data races in the program. AddStandardScheme
- // isn't threadsafe so must be called when GURL isn't used on any other
- // thread. This is really easy to mess up, so we say that all calls to
- // AddStandardScheme in Chrome must be inside this function.
- if (lock_standard_schemes)
- url::LockStandardSchemes();
+
+ for (const url::SchemeWithType& scheme : additional_standard_schemes)
+ url::AddStandardScheme(scheme.scheme, scheme.type);
+
+ for (const url::SchemeWithType& scheme : additional_referrer_schemes)
+ url::AddReferrerScheme(scheme.scheme, scheme.type);
+
+ // Prevent future modification of the scheme lists. This is to prevent
+ // accidental creation of data races in the program. Add*Scheme aren't
+ // threadsafe so must be called when GURL isn't used on any other thread. This
+ // is really easy to mess up, so we say that all calls to Add*Scheme in Chrome
+ // must be inside this function.
+ if (lock_schemes)
+ url::LockSchemeRegistries();
// We rely on the above lock to protect this part from being invoked twice.
if (!additional_savable_schemes.empty()) {
diff --git a/chromium/content/common/url_schemes.h b/chromium/content/common/url_schemes.h
index 571c660f217..1441c9c9ab0 100644
--- a/chromium/content/common/url_schemes.h
+++ b/chromium/content/common/url_schemes.h
@@ -10,16 +10,16 @@
namespace content {
// Note: ContentMainRunner calls this method internally as part of main
-// initialziation, so this function generally should not be called by
+// initialization, so this function generally should not be called by
// embedders. It's exported to facilitate test harnesses that do not
// utilize ContentMainRunner and that do not wish to lock the set
// of standard schemes at init time.
//
-// Called near the beginning of startup to register URL schemes that should
-// be parsed as "standard" with the src/url/ library. Optionally, the set
-// of standard schemes is locked down. The embedder can add additional
-// schemes by overriding the ContentClient::AddAdditionalSchemes method.
-CONTENT_EXPORT void RegisterContentSchemes(bool lock_standard_schemes);
+// Called near the beginning of startup to register URL schemes that should be
+// parsed as "standard" or "referrer" with the src/url/ library. Optionally, the
+// sets of schemes are locked down. The embedder can add additional schemes by
+// overriding the ContentClient::AddAdditionalSchemes method.
+CONTENT_EXPORT void RegisterContentSchemes(bool lock_schemes);
} // namespace content
diff --git a/chromium/content/common/utility_messages.h b/chromium/content/common/utility_messages.h
index a76986ede7c..6a43e5a1f2d 100644
--- a/chromium/content/common/utility_messages.h
+++ b/chromium/content/common/utility_messages.h
@@ -4,15 +4,7 @@
// Multiply-included message file, so no include guard.
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "build/build_config.h"
#include "content/common/content_export.h"
-#include "content/public/common/common_param_traits.h"
-#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_message_macros.h"
#undef IPC_MESSAGE_EXPORT
@@ -28,27 +20,3 @@ IPC_MESSAGE_CONTROL0(UtilityMsg_BatchMode_Started)
// Tells the utility process that it can shutdown.
IPC_MESSAGE_CONTROL0(UtilityMsg_BatchMode_Finished)
-
-#if defined(OS_POSIX) && defined(ENABLE_PLUGINS)
-// Tells the utility process to load each plugin in the order specified by the
-// vector. It will respond after each load with the WebPluginInfo.
-IPC_MESSAGE_CONTROL1(UtilityMsg_LoadPlugins,
- std::vector<base::FilePath> /* plugin paths */)
-#endif
-
-//------------------------------------------------------------------------------
-// Utility process host messages:
-// These are messages from the utility process to the browser.
-
-#if defined(OS_POSIX) && defined(ENABLE_PLUGINS)
-// Notifies the browser when a plugin failed to load so the two processes can
-// keep the canonical list in sync.
-IPC_SYNC_MESSAGE_CONTROL2_0(UtilityHostMsg_LoadPluginFailed,
- uint32_t /* index in the vector */,
- base::FilePath /* path of plugin */)
-
-// Notifies the browser that a plugin in the vector sent by it has been loaded.
-IPC_SYNC_MESSAGE_CONTROL2_0(UtilityHostMsg_LoadedPlugin,
- uint32_t /* index in the vector */,
- content::WebPluginInfo /* plugin info */)
-#endif
diff --git a/chromium/content/common/view_messages.h b/chromium/content/common/view_messages.h
index 5b5e578b7dd..324bdef3c51 100644
--- a/chromium/content/common/view_messages.h
+++ b/chromium/content/common/view_messages.h
@@ -22,8 +22,8 @@
#include "content/common/frame_replication_state.h"
#include "content/common/media/media_param_traits.h"
#include "content/common/navigation_gesture.h"
+#include "content/common/resize_params.h"
#include "content/common/view_message_enums.h"
-#include "content/common/webplugin_geometry.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_file_info.h"
@@ -34,7 +34,6 @@
#include "content/public/common/page_zoom.h"
#include "content/public/common/referrer.h"
#include "content/public/common/renderer_preferences.h"
-#include "content/public/common/stop_find_action.h"
#include "content/public/common/three_d_api_types.h"
#include "content/public/common/window_container_type.h"
#include "ipc/ipc_channel_handle.h"
@@ -49,7 +48,6 @@
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h"
#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
-#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebMediaPlayerAction.h"
#include "third_party/WebKit/public/web/WebPluginAction.h"
#include "third_party/WebKit/public/web/WebPopupType.h"
@@ -66,6 +64,7 @@
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
#include "ui/gfx/range/range.h"
#if defined(OS_MACOSX)
@@ -111,8 +110,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(gfx::FontRenderParams::SubpixelRendering,
gfx::FontRenderParams::SUBPIXEL_RENDERING_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(content::TapMultipleTargetsStrategy,
content::TAP_MULTIPLE_TARGETS_STRATEGY_MAX)
-IPC_ENUM_TRAITS_MAX_VALUE(content::StopFindAction,
- content::STOP_FIND_ACTION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::ThreeDAPIType,
content::THREE_D_API_TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(media::MediaLogEvent::Type,
@@ -128,12 +125,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(
IPC_ENUM_TRAITS_MAX_VALUE(blink::ScrollerStyle, blink::ScrollerStyleOverlay)
#endif
-IPC_STRUCT_TRAITS_BEGIN(blink::WebFindOptions)
- IPC_STRUCT_TRAITS_MEMBER(forward)
- IPC_STRUCT_TRAITS_MEMBER(matchCase)
- IPC_STRUCT_TRAITS_MEMBER(findNext)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(blink::WebMediaPlayerAction)
IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(enable)
@@ -170,6 +161,8 @@ IPC_STRUCT_TRAITS_BEGIN(blink::WebDeviceEmulationParams)
IPC_STRUCT_TRAITS_MEMBER(fitToView)
IPC_STRUCT_TRAITS_MEMBER(offset)
IPC_STRUCT_TRAITS_MEMBER(scale)
+ IPC_STRUCT_TRAITS_MEMBER(screenOrientationAngle)
+ IPC_STRUCT_TRAITS_MEMBER(screenOrientationType)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(blink::WebScreenInfo)
@@ -183,6 +176,19 @@ IPC_STRUCT_TRAITS_BEGIN(blink::WebScreenInfo)
IPC_STRUCT_TRAITS_MEMBER(orientationAngle)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(content::ResizeParams)
+ IPC_STRUCT_TRAITS_MEMBER(screen_info)
+ IPC_STRUCT_TRAITS_MEMBER(new_size)
+ IPC_STRUCT_TRAITS_MEMBER(physical_backing_size)
+ IPC_STRUCT_TRAITS_MEMBER(top_controls_shrink_blink_size)
+ IPC_STRUCT_TRAITS_MEMBER(top_controls_height)
+ IPC_STRUCT_TRAITS_MEMBER(visible_viewport_size)
+ IPC_STRUCT_TRAITS_MEMBER(resizer_rect)
+ IPC_STRUCT_TRAITS_MEMBER(is_fullscreen_granted)
+ IPC_STRUCT_TRAITS_MEMBER(display_mode)
+ IPC_STRUCT_TRAITS_MEMBER(needs_resize_ack)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::MenuItem)
IPC_STRUCT_TRAITS_MEMBER(label)
IPC_STRUCT_TRAITS_MEMBER(tool_tip)
@@ -279,15 +285,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences)
IPC_STRUCT_TRAITS_MEMBER(default_font_size)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::WebPluginGeometry)
- IPC_STRUCT_TRAITS_MEMBER(window)
- IPC_STRUCT_TRAITS_MEMBER(window_rect)
- IPC_STRUCT_TRAITS_MEMBER(clip_rect)
- IPC_STRUCT_TRAITS_MEMBER(cutout_rects)
- IPC_STRUCT_TRAITS_MEMBER(rects_valid)
- IPC_STRUCT_TRAITS_MEMBER(visible)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(media::MediaLogEvent)
IPC_STRUCT_TRAITS_MEMBER(id)
IPC_STRUCT_TRAITS_MEMBER(type)
@@ -382,6 +379,9 @@ IPC_STRUCT_BEGIN(ViewHostMsg_CreateWorker_Params)
// RenderFrame routing id used to send messages back to the parent.
IPC_STRUCT_MEMBER(int, render_frame_route_id)
+ // Address space of the context that created the worker.
+ IPC_STRUCT_MEMBER(blink::WebAddressSpace, creation_address_space)
+
// The type (secure or nonsecure) of the context that created the worker.
IPC_STRUCT_MEMBER(blink::WebSharedWorkerCreationContextType,
creation_context_type)
@@ -460,10 +460,6 @@ IPC_STRUCT_BEGIN(ViewHostMsg_UpdateRect_Params)
// view size.
IPC_STRUCT_MEMBER(gfx::Size, view_size)
- // New window locations for plugin child windows.
- IPC_STRUCT_MEMBER(std::vector<content::WebPluginGeometry>,
- plugin_window_moves)
-
// The following describes the various bits that may be set in flags:
//
// ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
@@ -479,34 +475,6 @@ IPC_STRUCT_BEGIN(ViewHostMsg_UpdateRect_Params)
IPC_STRUCT_MEMBER(int, flags)
IPC_STRUCT_END()
-IPC_STRUCT_BEGIN(ViewMsg_Resize_Params)
- // Information about the screen (dpi, depth, etc..).
- IPC_STRUCT_MEMBER(blink::WebScreenInfo, screen_info)
- // The size of the renderer.
- IPC_STRUCT_MEMBER(gfx::Size, new_size)
- // The size of the view's backing surface in non-DPI-adjusted pixels.
- IPC_STRUCT_MEMBER(gfx::Size, physical_backing_size)
- // Whether or not Blink's viewport size should be shrunk by the height of the
- // URL-bar (always false on platforms where URL-bar hiding isn't supported).
- IPC_STRUCT_MEMBER(bool, top_controls_shrink_blink_size)
- // The height of the top controls (always 0 on platforms where URL-bar hiding
- // isn't supported).
- IPC_STRUCT_MEMBER(float, top_controls_height)
- // The size of the visible viewport, which may be smaller than the view if the
- // view is partially occluded (e.g. by a virtual keyboard). The size is in
- // DPI-adjusted pixels.
- IPC_STRUCT_MEMBER(gfx::Size, visible_viewport_size)
- // The resizer rect.
- IPC_STRUCT_MEMBER(gfx::Rect, resizer_rect)
- // Indicates whether tab-initiated fullscreen was granted.
- IPC_STRUCT_MEMBER(bool, is_fullscreen_granted)
- // The display mode.
- IPC_STRUCT_MEMBER(blink::WebDisplayMode, display_mode)
- // If set, requests the renderer to reply with a ViewHostMsg_UpdateRect
- // with the ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK bit set in flags.
- IPC_STRUCT_MEMBER(bool, needs_resize_ack)
-IPC_STRUCT_END()
-
IPC_STRUCT_BEGIN(ViewMsg_New_Params)
// Renderer-wide preferences.
IPC_STRUCT_MEMBER(content::RendererPreferences, renderer_preferences)
@@ -558,7 +526,7 @@ IPC_STRUCT_BEGIN(ViewMsg_New_Params)
IPC_STRUCT_MEMBER(int32_t, next_page_id)
// The initial renderer size.
- IPC_STRUCT_MEMBER(ViewMsg_Resize_Params, initial_size)
+ IPC_STRUCT_MEMBER(content::ResizeParams, initial_size)
// Whether to enable auto-resize.
IPC_STRUCT_MEMBER(bool, enable_auto_resize)
@@ -577,7 +545,6 @@ IPC_STRUCT_BEGIN(ViewMsg_UpdateScrollbarTheme_Params)
IPC_STRUCT_MEMBER(bool, jump_on_track_click)
IPC_STRUCT_MEMBER(blink::ScrollerStyle, preferred_scroller_style)
IPC_STRUCT_MEMBER(bool, redraw)
- IPC_STRUCT_MEMBER(bool, scroll_animation_enabled)
IPC_STRUCT_MEMBER(blink::WebScrollbarButtonsPlacement, button_placement)
IPC_STRUCT_END()
#endif
@@ -642,8 +609,7 @@ IPC_MESSAGE_ROUTED0(ViewMsg_Close)
// the view's current size. The generated ViewHostMsg_UpdateRect message will
// have the IS_RESIZE_ACK flag set. It also receives the resizer rect so that
// we don't have to fetch it every time WebKit asks for it.
-IPC_MESSAGE_ROUTED1(ViewMsg_Resize,
- ViewMsg_Resize_Params /* params */)
+IPC_MESSAGE_ROUTED1(ViewMsg_Resize, content::ResizeParams /* params */)
// Enables device emulation. See WebDeviceEmulationParams for description.
IPC_MESSAGE_ROUTED1(ViewMsg_EnableDeviceEmulation,
@@ -684,17 +650,6 @@ IPC_MESSAGE_ROUTED2(ViewMsg_ShowContextMenu,
ui::MenuSourceType,
gfx::Point /* location where menu should be shown */)
-// Sent when the user wants to search for a word on the page (find in page).
-IPC_MESSAGE_ROUTED3(ViewMsg_Find,
- int /* request_id */,
- base::string16 /* search_text */,
- blink::WebFindOptions)
-
-// This message notifies the renderer that the user has closed the FindInPage
-// window (and what action to take regarding the selection).
-IPC_MESSAGE_ROUTED1(ViewMsg_StopFinding,
- content::StopFindAction /* action */)
-
// Copies the image at location x, y to the clipboard (if there indeed is an
// image at that location).
IPC_MESSAGE_ROUTED2(ViewMsg_CopyImageAt,
@@ -779,11 +734,6 @@ IPC_MESSAGE_ROUTED2(ViewMsg_EnumerateDirectoryResponse,
int /* request_id */,
std::vector<base::FilePath> /* files_in_directory */)
-// Tells the renderer to suppress any further modal dialogs until it receives a
-// corresponding ViewMsg_SwapOut message. This ensures that no
-// PageGroupLoadDeferrer is on the stack for SwapOut.
-IPC_MESSAGE_ROUTED0(ViewMsg_SuppressDialogsUntilSwapOut)
-
// Instructs the renderer to close the current page, including running the
// onunload event handler.
//
@@ -867,6 +817,10 @@ IPC_MESSAGE_CONTROL2(ViewMsg_NetworkConnectionChanged,
net::NetworkChangeNotifier::ConnectionType /* type */,
double /* max bandwidth mbps */)
+// Sent by the browser to synchronize with the next compositor frame. Used only
+// for tests.
+IPC_MESSAGE_ROUTED1(ViewMsg_WaitForNextFrameForTests, int /* routing_id */)
+
#if defined(ENABLE_PLUGINS)
// Reply to ViewHostMsg_OpenChannelToPpapiBroker
// Tells the renderer that the channel to the broker has been created.
@@ -886,9 +840,6 @@ IPC_MESSAGE_CONTROL1(ViewMsg_PurgePluginListCache,
bool /* reload_pages */)
#endif
-// Used to instruct the RenderView to go into "view source" mode.
-IPC_MESSAGE_ROUTED0(ViewMsg_EnableViewSourceMode)
-
// An acknowledge to ViewHostMsg_MultipleTargetsTouched to notify the renderer
// process to release the magnified image.
IPC_MESSAGE_ROUTED1(ViewMsg_ReleaseDisambiguationPopupBitmap,
@@ -914,19 +865,6 @@ IPC_MESSAGE_CONTROL3(ViewMsg_SystemColorsChanged,
IPC_MESSAGE_CONTROL1(ViewMsg_SetWebKitSharedTimersSuspended,
bool /* suspend */)
-// Sent when the browser wants the bounding boxes of the current find matches.
-//
-// If match rects are already cached on the browser side, |current_version|
-// should be the version number from the ViewHostMsg_FindMatchRects_Reply
-// they came in, so the renderer can tell if it needs to send updated rects.
-// Otherwise just pass -1 to always receive the list of rects.
-//
-// There must be an active search string (it is probably most useful to call
-// this immediately after a ViewHostMsg_Find_Reply message arrives with
-// final_update set to true).
-IPC_MESSAGE_ROUTED1(ViewMsg_FindMatchRects,
- int /* current_version */)
-
// Notifies the renderer whether hiding/showing the top controls is enabled
// and whether or not to animate to the proper state.
IPC_MESSAGE_ROUTED3(ViewMsg_UpdateTopControlsState,
@@ -940,26 +878,6 @@ IPC_MESSAGE_ROUTED0(ViewMsg_ShowImeIfNeeded)
// ViewHostMsg_SmartClipDataExtracted IPC.
IPC_MESSAGE_ROUTED1(ViewMsg_ExtractSmartClipData,
gfx::Rect /* rect */)
-
-#elif defined(OS_MACOSX)
-// Let the RenderView know its window has changed visibility.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetWindowVisibility,
- bool /* visibile */)
-
-// Let the RenderView know its window's frame has changed.
-IPC_MESSAGE_ROUTED2(ViewMsg_WindowFrameChanged,
- gfx::Rect /* window frame */,
- gfx::Rect /* content view frame */)
-
-// Message sent from the browser to the renderer when the user starts or stops
-// resizing the view.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetInLiveResize,
- bool /* enable */)
-
-// Tell the renderer that plugin IME has completed.
-IPC_MESSAGE_ROUTED2(ViewMsg_PluginImeCompositionCompleted,
- base::string16 /* text */,
- int /* plugin_id */)
#endif
// Sent by the browser as a reply to ViewHostMsg_SwapCompositorFrame.
@@ -1071,19 +989,6 @@ IPC_MESSAGE_ROUTED0(ViewHostMsg_UpdateScreenRects_ACK)
IPC_MESSAGE_ROUTED1(ViewHostMsg_RequestMove,
gfx::Rect /* position */)
-// Result of string search in the page.
-// Response to ViewMsg_Find with the results of the requested find-in-page
-// search, the number of matches found and the selection rect (in screen
-// coordinates) for the string found. If |final_update| is false, it signals
-// that this is not the last Find_Reply message - more will be sent as the
-// scoping effort continues.
-IPC_MESSAGE_ROUTED5(ViewHostMsg_Find_Reply,
- int /* request_id */,
- int /* number of matches */,
- gfx::Rect /* selection_rect */,
- int /* active_match_ordinal */,
- bool /* final_update */)
-
// Indicates that the render view has been closed in respose to a
// Close message.
IPC_MESSAGE_CONTROL1(ViewHostMsg_Close_ACK,
@@ -1127,14 +1032,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_FocusedNodeChanged,
IPC_MESSAGE_ROUTED1(ViewHostMsg_SetCursor, content::WebCursor)
-#if defined(OS_WIN)
-IPC_MESSAGE_ROUTED1(ViewHostMsg_WindowlessPluginDummyWindowCreated,
- gfx::NativeViewId /* dummy_activation_window */)
-
-IPC_MESSAGE_ROUTED1(ViewHostMsg_WindowlessPluginDummyWindowDestroyed,
- gfx::NativeViewId /* dummy_activation_window */)
-#endif
-
// Get the list of proxies to use for |url|, as a semicolon delimited list
// of "<TYPE> <HOST>:<PORT>" | "DIRECT".
IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_ResolveProxy,
@@ -1221,7 +1118,7 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_SetTooltipText,
// text in the document.
IPC_MESSAGE_ROUTED3(ViewHostMsg_SelectionChanged,
base::string16 /* text covers the selection range */,
- size_t /* the offset of the text in the document */,
+ uint32_t /* the offset of the text in the document */,
gfx::Range /* selection range in the document */)
// Notification that the selection bounds have changed.
@@ -1363,27 +1260,10 @@ IPC_MESSAGE_ROUTED0(ViewHostMsg_DidFirstPaintAfterLoad)
IPC_MESSAGE_ROUTED1(ViewHostMsg_ForwardCompositorProto,
std::vector<uint8_t> /* proto */)
-#if defined(OS_ANDROID)
-// Response to ViewMsg_FindMatchRects.
-//
-// |version| will contain the current version number of the renderer's find
-// match list (incremented whenever they change), which should be passed in the
-// next call to ViewMsg_FindMatchRects.
-//
-// |rects| will either contain a list of the enclosing rects of all matches
-// found by the most recent Find operation, or will be empty if |version| is not
-// greater than the |current_version| passed to ViewMsg_FindMatchRects (hence
-// your locally cached rects should still be valid). The rect coords will be
-// custom normalized fractions of the document size. The rects will be sorted by
-// frame traversal order starting in the main frame, then by dom order.
-//
-// |active_rect| will contain the bounding box of the active find-in-page match
-// marker, in similarly normalized coords (or an empty rect if there isn't one).
-IPC_MESSAGE_ROUTED3(ViewHostMsg_FindMatchRects_Reply,
- int /* version */,
- std::vector<gfx::RectF> /* rects */,
- gfx::RectF /* active_rect */)
+// Sent in reply to ViewMsg_WaitForNextFrameForTests.
+IPC_MESSAGE_ROUTED0(ViewHostMsg_WaitForNextFrameForTests_ACK)
+#if defined(OS_ANDROID)
// Start an android intent with the given URI.
IPC_MESSAGE_ROUTED2(ViewHostMsg_StartContentIntent,
GURL /* content_url */,
@@ -1402,14 +1282,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_ShowUnhandledTapUIIfNeeded,
int /* y */)
#elif defined(OS_MACOSX)
-// Informs the browser that a plugin has gained or lost focus.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_PluginFocusChanged,
- bool, /* focused */
- int /* plugin_id */)
-
-// Instructs the browser to start plugin IME.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_StartPluginIme)
-
// Receives content of a web page as plain text.
IPC_MESSAGE_ROUTED1(ViewMsg_GetRenderedTextCompleted, std::string)
#endif
diff --git a/chromium/content/common/vr_service.mojom b/chromium/content/common/vr_service.mojom
index 2d81ec70a11..5e90880a519 100644
--- a/chromium/content/common/vr_service.mojom
+++ b/chromium/content/common/vr_service.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
struct VRVector3 {
float x;
diff --git a/chromium/content/common/wake_lock_service.mojom b/chromium/content/common/wake_lock_service.mojom
index 3d6e6d896c9..452d9342cda 100644
--- a/chromium/content/common/wake_lock_service.mojom
+++ b/chromium/content/common/wake_lock_service.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-module content;
+module content.mojom;
// WebLockService receives per-frame wake lock preference from its client.
interface WakeLockService {
diff --git a/chromium/content/common/webplugin_geometry.cc b/chromium/content/common/webplugin_geometry.cc
deleted file mode 100644
index ff290d20001..00000000000
--- a/chromium/content/common/webplugin_geometry.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 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 "content/common/webplugin_geometry.h"
-
-namespace content {
-
-WebPluginGeometry::WebPluginGeometry()
- : window(gfx::kNullPluginWindow),
- rects_valid(false),
- visible(false) {
-}
-
-WebPluginGeometry::~WebPluginGeometry() {
-}
-
-bool WebPluginGeometry::Equals(const WebPluginGeometry& rhs) const {
- return window == rhs.window &&
- window_rect == rhs.window_rect &&
- clip_rect == rhs.clip_rect &&
- cutout_rects == rhs.cutout_rects &&
- rects_valid == rhs.rects_valid &&
- visible == rhs.visible;
-}
-
-} // namespace content
diff --git a/chromium/content/common/webplugin_geometry.h b/chromium/content/common/webplugin_geometry.h
deleted file mode 100644
index 7f727a1317e..00000000000
--- a/chromium/content/common/webplugin_geometry.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2013 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 CONTENT_COMMON_WEBPLUGIN_GEOMETRY_H_
-#define CONTENT_COMMON_WEBPLUGIN_GEOMETRY_H_
-
-#include <vector>
-
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace content {
-
-// Describes the new location for a plugin window.
-struct WebPluginGeometry {
- WebPluginGeometry();
- ~WebPluginGeometry();
-
- bool Equals(const WebPluginGeometry& rhs) const;
-
- // On Windows, this is the plugin window in the plugin process.
- // On X11, this is the XID of the plugin-side GtkPlug containing the
- // GtkSocket hosting the actual plugin window.
- //
- // On Mac OS X, all of the plugin types are currently "windowless"
- // (window == 0) except for the special case of the GPU plugin,
- // which currently performs rendering on behalf of the Pepper 3D API
- // and WebGL. The GPU plugin uses a simple integer for the
- // PluginWindowHandle which is used to map to a side data structure
- // containing information about the plugin. Soon this plugin will be
- // generalized, at which point this mechanism will be rethought or
- // removed.
- gfx::PluginWindowHandle window;
- gfx::Rect window_rect;
- // Clip rect (include) and cutouts (excludes), relative to
- // window_rect origin.
- gfx::Rect clip_rect;
- std::vector<gfx::Rect> cutout_rects;
- bool rects_valid;
- bool visible;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_WEBPLUGIN_GEOMETRY_H_
diff --git a/chromium/content/common/websocket_messages.h b/chromium/content/common/websocket_messages.h
index e0af254960e..383eb5a1f4a 100644
--- a/chromium/content/common/websocket_messages.h
+++ b/chromium/content/common/websocket_messages.h
@@ -73,6 +73,23 @@ IPC_MESSAGE_ROUTED4(WebSocketHostMsg_AddChannelRequest,
url::Origin /* origin */,
int /* render_frame_id */)
+// Send a complete binary WebSocket message consisting of the Blob identified by
+// |uuid|. The message will be split into frames as necessary. |expected_size|
+// must match the browser's idea of the size of the Blob to prevent flow control
+// from becoming desynchronised. If it does not match the connection will be
+// terminated with a WebSocketMsg_NotifyFailure message. On success, the browser
+// will have consumed |expected_size| bytes of flow control send quota and the
+// renderer needs to subtract that from its running total of flow control send
+// quota. See the design doc at
+// https://docs.google.com/document/d/1CDiXB9pBumhFVVfmIn1CRI6v6byxyqWu2urEE9xp714/edit
+// SendFrame or SendBlob IPCs must not be sent by the renderer until the
+// BlobSendComplete message has been received from the browser. The renderer
+// should retain a reference to the Blob until either a BlobSendComplete or
+// NotifyFailure IPC is received.
+IPC_MESSAGE_ROUTED2(WebSocketHostMsg_SendBlob,
+ std::string /* uuid */,
+ uint64_t /* expected_size */)
+
// WebSocket messages sent from the browser to the renderer.
// Respond to an AddChannelRequest. |selected_protocol| is the sub-protocol the
@@ -111,6 +128,11 @@ IPC_MESSAGE_ROUTED1(WebSocketMsg_NotifyFinishOpeningHandshake,
IPC_MESSAGE_ROUTED1(WebSocketMsg_NotifyFailure,
std::string /* message */)
+// Indicates tbat the current Blob has finished sending. The renderer can
+// release its reference on the Blob, and may now use SendFrame or SendBlob to
+// send more messages.
+IPC_MESSAGE_ROUTED0(WebSocketMsg_BlobSendComplete)
+
// WebSocket messages that can be sent in either direction.
// Send a non-control frame to the channel.
@@ -136,6 +158,14 @@ IPC_MESSAGE_ROUTED3(WebSocketMsg_SendFrame,
// Both sides start a new channel with a quota of 0, and must wait for a
// FlowControl message before calling SendFrame. The total available quota on
// one side must never exceed 0x7FFFFFFFFFFFFFFF tokens.
+//
+// During "blob sending mode", ie. between the renderer sending a
+// WebSocketHostMsg_SendBlob IPC and receiving a WebSocketMsg_BlobSendComplete
+// IPC, quota is used up in the browser process to send the blob, but
+// FlowControl IPCs for that quota are still sent to the renderer. The render
+// process needs to take into account that quota equal to the size of the Blob
+// has already been used when calculating how much send quota it has left after
+// receiving BlobSendComplete.
IPC_MESSAGE_ROUTED1(WebSocketMsg_FlowControl, int64_t /* quota */)
// Drop the channel.
diff --git a/chromium/content/common/worker_messages.h b/chromium/content/common/worker_messages.h
index 60f1a4a9d10..e49ce80e525 100644
--- a/chromium/content/common/worker_messages.h
+++ b/chromium/content/common/worker_messages.h
@@ -41,6 +41,7 @@ IPC_STRUCT_BEGIN(WorkerProcessMsg_CreateWorker_Params)
IPC_STRUCT_MEMBER(base::string16, name)
IPC_STRUCT_MEMBER(base::string16, content_security_policy)
IPC_STRUCT_MEMBER(blink::WebContentSecurityPolicyType, security_policy_type)
+ IPC_STRUCT_MEMBER(blink::WebAddressSpace, creation_address_space)
IPC_STRUCT_MEMBER(bool, pause_on_start)
IPC_STRUCT_MEMBER(int, route_id)
IPC_STRUCT_END()
@@ -55,16 +56,6 @@ IPC_MESSAGE_CONTROL1(WorkerProcessMsg_CreateWorker,
// WorkerProcessHost messages
// These are messages sent from the worker process to the browser process.
-// Sent by the worker process to check whether access to web databases is
-// allowed.
-IPC_SYNC_MESSAGE_CONTROL5_1(WorkerProcessHostMsg_AllowDatabase,
- int /* worker_route_id */,
- GURL /* origin url */,
- base::string16 /* database name */,
- base::string16 /* database display name */,
- unsigned long /* estimated size */,
- bool /* result */)
-
// Sent by the worker process to check whether access to file system is allowed.
IPC_SYNC_MESSAGE_CONTROL2_1(WorkerProcessHostMsg_RequestFileSystemAccessSync,
int /* worker_route_id */,