0

[NaCl SDK Docs] Check in the generated NaCl SDK Documentation.

This is necessary so that the Chromesite server can poll for changes and
automatically update.

I can't upload the full docs/images to Rietveld, so this review will
just be empty and I'll manually commit.

BUG=none
R=awatson@chromium.org, sbc@chromium.org

Review URL: https://codereview.chromium.org/140993006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246665 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
binji@chromium.org
2014-01-23 19:26:04 +00:00
parent 9fd50a9395
commit bde3d5d020
1545 changed files with 125771 additions and 1 deletions
native_client_sdk
doc_generated
.buildinfo
_static
community
devguide
faq.htmlglossary.htmlhelp.html
images
index.htmlnacl-and-pnacl.htmloverview.html
pepper_beta
c
globals_defs.htmlgroup___enums.htmlgroup___functions.htmlgroup___interfaces.htmlgroup___structs.htmlgroup___typedefs.htmlindex.htmlindex.rstpp__array__output_8h.htmlpp__array__output_8h__incl.pngpp__bool_8h.htmlpp__bool_8h__incl.pngpp__completion__callback_8h.htmlpp__completion__callback_8h__incl.pngpp__directory__entry_8h.htmlpp__directory__entry_8h__incl.pngpp__errors_8h.htmlpp__errors_8h__incl.pngpp__file__info_8h.htmlpp__file__info_8h__incl.pngpp__graphics__3d_8h.htmlpp__graphics__3d_8h__incl.pngpp__input__event_8h.htmlpp__input__event_8h__incl.pngpp__instance_8h.htmlpp__instance_8h__incl.pngpp__module_8h.htmlpp__module_8h__incl.pngpp__point_8h.htmlpp__point_8h__incl.pngpp__rect_8h.htmlpp__rect_8h__incl.pngpp__resource_8h.htmlpp__resource_8h__incl.pngpp__size_8h.htmlpp__size_8h__incl.pngpp__stdint_8h.htmlpp__stdint_8h__incl.pngpp__time_8h.htmlpp__time_8h__incl.pngpp__touch__point_8h.htmlpp__touch__point_8h__incl.pngpp__var_8h.htmlpp__var_8h__incl.pngppb_8h.htmlppb_8h__incl.pngppb__audio_8h.htmlppb__audio_8h__incl.pngppb__audio__config_8h.htmlppb__audio__config_8h__incl.pngppb__console_8h.htmlppb__console_8h__incl.pngppb__core_8h.htmlppb__core_8h__incl.pngppb__file__io_8h.htmlppb__file__io_8h__incl.pngppb__file__ref_8h.htmlppb__file__ref_8h__incl.pngppb__file__system_8h.htmlppb__file__system_8h__incl.pngppb__fullscreen_8h.htmlppb__fullscreen_8h__incl.pngppb__gamepad_8h.htmlppb__gamepad_8h__incl.pngppb__graphics__2d_8h.htmlppb__graphics__2d_8h__incl.pngppb__graphics__3d_8h.htmlppb__graphics__3d_8h__incl.pngppb__host__resolver_8h.htmlppb__host__resolver_8h__incl.pngppb__image__data_8h.htmlppb__image__data_8h__incl.pngppb__input__event_8h.htmlppb__input__event_8h__incl.pngppb__instance_8h.htmlppb__instance_8h__incl.pngppb__message__loop_8h.htmlppb__message__loop_8h__incl.pngppb__messaging_8h.htmlppb__messaging_8h__incl.pngppb__mouse__cursor_8h.htmlppb__mouse__cursor_8h__incl.pngppb__mouse__lock_8h.htmlppb__mouse__lock_8h__incl.pngppb__net__address_8h.htmlppb__net__address_8h__incl.pngppb__network__list_8h.htmlppb__network__list_8h__incl.pngppb__network__monitor_8h.htmlppb__network__monitor_8h__incl.pngppb__network__proxy_8h.htmlppb__network__proxy_8h__incl.pngppb__tcp__socket_8h.htmlppb__tcp__socket_8h__incl.pngppb__text__input__controller_8h.htmlppb__text__input__controller_8h__incl.pngppb__udp__socket_8h.htmlppb__udp__socket_8h__incl.pngppb__url__loader_8h.htmlppb__url__loader_8h__incl.pngppb__url__request__info_8h.htmlppb__url__request__info_8h__incl.pngppb__url__response__info_8h.htmlppb__url__response__info_8h__incl.pngppb__var_8h.htmlppb__var_8h__incl.pngppb__var__array_8h.htmlppb__var__array_8h__incl.pngppb__var__array__buffer_8h.htmlppb__var__array__buffer_8h__incl.pngppb__var__dictionary_8h.htmlppb__var__dictionary_8h__incl.pngppb__view_8h.htmlppb__view_8h__incl.pngppb__websocket_8h.htmlppb__websocket_8h__incl.pngppp_8h.htmlppp_8h__incl.pngppp__graphics__3d_8h.htmlppp__graphics__3d_8h__incl.pngppp__input__event_8h.htmlppp__input__event_8h__incl.pngppp__instance_8h.htmlppp__instance_8h__incl.pngppp__messaging_8h.htmlppp__messaging_8h__incl.pngppp__mouse__lock_8h.htmlppp__mouse__lock_8h__incl.pngstruct_p_p___array_output.htmlstruct_p_p___completion_callback.htmlstruct_p_p___directory_entry.htmlstruct_p_p___file_info.htmlstruct_p_p___float_point.htmlstruct_p_p___gamepad_sample_data.htmlstruct_p_p___gamepads_sample_data.htmlstruct_p_p___host_resolver___hint.htmlstruct_p_p___image_data_desc.htmlstruct_p_p___input_event___character.htmlstruct_p_p___input_event___key.htmlstruct_p_p___input_event___mouse.htmlstruct_p_p___input_event___wheel.htmlstruct_p_p___net_address___i_pv4.htmlstruct_p_p___net_address___i_pv6.htmlstruct_p_p___point.htmlstruct_p_p___rect.htmlstruct_p_p___size.htmlstruct_p_p___touch_point.htmlstruct_p_p___var.htmlstruct_p_p_b___audio__1__1.htmlstruct_p_p_b___audio_config__1__1.htmlstruct_p_p_b___console__1__0.htmlstruct_p_p_b___core__1__0.htmlstruct_p_p_b___file_i_o__1__1.htmlstruct_p_p_b___file_ref__1__1.htmlstruct_p_p_b___file_system__1__0.htmlstruct_p_p_b___fullscreen__1__0.htmlstruct_p_p_b___gamepad__1__0.htmlstruct_p_p_b___graphics2_d__1__1.htmlstruct_p_p_b___graphics3_d__1__0.htmlstruct_p_p_b___host_resolver__1__0.htmlstruct_p_p_b___i_m_e_input_event__1__0.htmlstruct_p_p_b___image_data__1__0.htmlstruct_p_p_b___input_event__1__0.htmlstruct_p_p_b___instance__1__0.htmlstruct_p_p_b___keyboard_input_event__1__0.htmlstruct_p_p_b___message_loop__1__0.htmlstruct_p_p_b___messaging__1__0.htmlstruct_p_p_b___mouse_cursor__1__0.htmlstruct_p_p_b___mouse_input_event__1__1.htmlstruct_p_p_b___mouse_lock__1__0.htmlstruct_p_p_b___net_address__1__0.htmlstruct_p_p_b___network_list__1__0.htmlstruct_p_p_b___network_monitor__1__0.htmlstruct_p_p_b___network_proxy__1__0.htmlstruct_p_p_b___t_c_p_socket__1__1.htmlstruct_p_p_b___text_input_controller__1__0.htmlstruct_p_p_b___touch_input_event__1__0.htmlstruct_p_p_b___u_d_p_socket__1__0.htmlstruct_p_p_b___u_r_l_loader__1__0.htmlstruct_p_p_b___u_r_l_request_info__1__0.htmlstruct_p_p_b___u_r_l_response_info__1__0.htmlstruct_p_p_b___var__1__1.htmlstruct_p_p_b___var_array__1__0.htmlstruct_p_p_b___var_array_buffer__1__0.htmlstruct_p_p_b___var_dictionary__1__0.htmlstruct_p_p_b___view__1__1.htmlstruct_p_p_b___web_socket__1__0.htmlstruct_p_p_b___wheel_input_event__1__0.htmlstruct_p_p_p___graphics3_d__1__0.htmlstruct_p_p_p___input_event__0__1.htmlstruct_p_p_p___instance__1__1.htmlstruct_p_p_p___messaging__1__0.htmlstruct_p_p_p___mouse_lock__1__0.htmlunion_p_p___var_value.html
cpp
audio_8h.htmlaudio_8h__incl.pngaudio__config_8h.htmlaudio__config_8h__incl.pngclasspp_1_1_audio-members.htmlclasspp_1_1_audio.htmlclasspp_1_1_audio__inherit__graph.pngclasspp_1_1_audio_config-members.htmlclasspp_1_1_audio_config.htmlclasspp_1_1_audio_config__inherit__graph.pngclasspp_1_1_completion_callback-members.htmlclasspp_1_1_completion_callback.htmlclasspp_1_1_completion_callback__inherit__graph.pngclasspp_1_1_completion_callback_factory-members.htmlclasspp_1_1_completion_callback_factory.htmlclasspp_1_1_completion_callback_with_output-members.htmlclasspp_1_1_completion_callback_with_output.htmlclasspp_1_1_completion_callback_with_output__inherit__graph.pngclasspp_1_1_core-members.htmlclasspp_1_1_core.htmlclasspp_1_1_directory_entry-members.htmlclasspp_1_1_directory_entry.htmlclasspp_1_1_file_i_o-members.htmlclasspp_1_1_file_i_o.htmlclasspp_1_1_file_i_o__inherit__graph.pngclasspp_1_1_file_ref-members.htmlclasspp_1_1_file_ref.htmlclasspp_1_1_file_ref__inherit__graph.pngclasspp_1_1_file_system-members.htmlclasspp_1_1_file_system.htmlclasspp_1_1_file_system__inherit__graph.pngclasspp_1_1_float_point-members.htmlclasspp_1_1_float_point.htmlclasspp_1_1_fullscreen-members.htmlclasspp_1_1_fullscreen.htmlclasspp_1_1_graphics2_d-members.htmlclasspp_1_1_graphics2_d.htmlclasspp_1_1_graphics2_d__inherit__graph.pngclasspp_1_1_graphics3_d-members.htmlclasspp_1_1_graphics3_d.htmlclasspp_1_1_graphics3_d__inherit__graph.pngclasspp_1_1_graphics3_d_client-members.htmlclasspp_1_1_graphics3_d_client.htmlclasspp_1_1_host_resolver-members.htmlclasspp_1_1_host_resolver.htmlclasspp_1_1_host_resolver__inherit__graph.pngclasspp_1_1_i_m_e_input_event-members.htmlclasspp_1_1_i_m_e_input_event.htmlclasspp_1_1_i_m_e_input_event__inherit__graph.pngclasspp_1_1_image_data-members.htmlclasspp_1_1_image_data.htmlclasspp_1_1_image_data__inherit__graph.pngclasspp_1_1_input_event-members.htmlclasspp_1_1_input_event.htmlclasspp_1_1_input_event__inherit__graph.pngclasspp_1_1_instance-members.htmlclasspp_1_1_instance.htmlclasspp_1_1_instance_handle-members.htmlclasspp_1_1_instance_handle.htmlclasspp_1_1_keyboard_input_event-members.htmlclasspp_1_1_keyboard_input_event.htmlclasspp_1_1_keyboard_input_event__inherit__graph.pngclasspp_1_1_message_loop-members.htmlclasspp_1_1_message_loop.htmlclasspp_1_1_message_loop__inherit__graph.pngclasspp_1_1_module-members.htmlclasspp_1_1_module.htmlclasspp_1_1_mouse_cursor-members.htmlclasspp_1_1_mouse_cursor.htmlclasspp_1_1_mouse_input_event-members.htmlclasspp_1_1_mouse_input_event.htmlclasspp_1_1_mouse_input_event__inherit__graph.pngclasspp_1_1_mouse_lock-members.htmlclasspp_1_1_mouse_lock.htmlclasspp_1_1_net_address-members.htmlclasspp_1_1_net_address.htmlclasspp_1_1_net_address__inherit__graph.pngclasspp_1_1_network_list-members.htmlclasspp_1_1_network_list.htmlclasspp_1_1_network_list__inherit__graph.pngclasspp_1_1_network_monitor-members.htmlclasspp_1_1_network_monitor.htmlclasspp_1_1_network_monitor__inherit__graph.pngclasspp_1_1_network_proxy-members.htmlclasspp_1_1_network_proxy.htmlclasspp_1_1_point-members.htmlclasspp_1_1_point.htmlclasspp_1_1_rect-members.htmlclasspp_1_1_rect.htmlclasspp_1_1_resource-members.htmlclasspp_1_1_resource.htmlclasspp_1_1_resource__inherit__graph.pngclasspp_1_1_size-members.htmlclasspp_1_1_size.htmlclasspp_1_1_t_c_p_socket-members.htmlclasspp_1_1_t_c_p_socket.htmlclasspp_1_1_t_c_p_socket__inherit__graph.pngclasspp_1_1_text_input_controller-members.htmlclasspp_1_1_text_input_controller.htmlclasspp_1_1_touch_input_event-members.htmlclasspp_1_1_touch_input_event.htmlclasspp_1_1_touch_input_event__inherit__graph.pngclasspp_1_1_touch_point-members.htmlclasspp_1_1_touch_point.htmlclasspp_1_1_u_d_p_socket-members.htmlclasspp_1_1_u_d_p_socket.htmlclasspp_1_1_u_d_p_socket__inherit__graph.pngclasspp_1_1_u_r_l_loader-members.htmlclasspp_1_1_u_r_l_loader.htmlclasspp_1_1_u_r_l_loader__inherit__graph.pngclasspp_1_1_u_r_l_request_info-members.htmlclasspp_1_1_u_r_l_request_info.htmlclasspp_1_1_u_r_l_request_info__inherit__graph.pngclasspp_1_1_u_r_l_response_info-members.htmlclasspp_1_1_u_r_l_response_info.htmlclasspp_1_1_u_r_l_response_info__inherit__graph.pngclasspp_1_1_var-members.htmlclasspp_1_1_var.htmlclasspp_1_1_var_1_1_out_exception-members.htmlclasspp_1_1_var_1_1_out_exception.htmlclasspp_1_1_var__inherit__graph.pngclasspp_1_1_var_array-members.htmlclasspp_1_1_var_array.htmlclasspp_1_1_var_array__inherit__graph.pngclasspp_1_1_var_array_buffer-members.htmlclasspp_1_1_var_array_buffer.htmlclasspp_1_1_var_array_buffer__inherit__graph.pngclasspp_1_1_var_dictionary-members.htmlclasspp_1_1_var_dictionary.htmlclasspp_1_1_var_dictionary__inherit__graph.pngclasspp_1_1_view-members.htmlclasspp_1_1_view.htmlclasspp_1_1_view__inherit__graph.pngclasspp_1_1_web_socket-members.htmlclasspp_1_1_web_socket.htmlclasspp_1_1_web_socket__inherit__graph.pngclasspp_1_1_wheel_input_event-members.htmlclasspp_1_1_wheel_input_event.htmlclasspp_1_1_wheel_input_event__inherit__graph.pngclasspp_1_1ext_1_1_ext_completion_callback_with_output-members.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output__inherit__graph.pngclasspp_1_1internal_1_1_completion_callback_with_output_base-members.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base__inherit__graph.pngclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage-members.htmlclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage.htmlcompletion__callback_8h.htmlcompletion__callback_8h__incl.pngcompletion__callback__factory_8h.htmlcompletion__callback__factory_8h__incl.pngcore_8h.htmlcore_8h__incl.pngdirectory__entry_8h.htmldirectory__entry_8h__incl.pngfile__io_8h.htmlfile__io_8h__incl.pngfile__ref_8h.htmlfile__ref_8h__incl.pngfile__system_8h.htmlfile__system_8h__incl.pngfullscreen_8h.htmlfullscreen_8h__incl.pngglobals_defs.htmlgraphics__2d_8h.htmlgraphics__2d_8h__incl.pnggraphics__3d_8h.htmlgraphics__3d_8h__incl.pnggraphics__3d__client_8h.htmlgraphics__3d__client_8h__incl.pnghost__resolver_8h.htmlhost__resolver_8h__incl.pngimage__data_8h.htmlimage__data_8h__incl.pngindex.htmlindex.rstinherit_graph_0.pnginherit_graph_1.pnginherit_graph_10.pnginherit_graph_11.pnginherit_graph_12.pnginherit_graph_13.pnginherit_graph_14.pnginherit_graph_15.pnginherit_graph_16.pnginherit_graph_17.pnginherit_graph_18.pnginherit_graph_19.pnginherit_graph_2.pnginherit_graph_20.pnginherit_graph_21.pnginherit_graph_22.pnginherit_graph_23.pnginherit_graph_24.pnginherit_graph_25.pnginherit_graph_26.pnginherit_graph_27.pnginherit_graph_3.pnginherit_graph_4.pnginherit_graph_5.pnginherit_graph_6.pnginherit_graph_7.pnginherit_graph_8.pnginherit_graph_9.pnginherits.htmlinput__event_8h.htmlinput__event_8h__incl.pnginstance_8h.htmlinstance_8h__incl.pnginstance__handle_8h.htmlinstance__handle_8h__incl.pnglogging_8h.htmllogging_8h__incl.pngmessage__loop_8h.htmlmessage__loop_8h__incl.pngmodule_8h.htmlmodule_8h__incl.pngmodule__embedder_8h.htmlmodule__embedder_8h__incl.pngmodule__impl_8h.htmlmodule__impl_8h__incl.pngmouse__cursor_8h.htmlmouse__cursor_8h__incl.pngmouse__lock_8h.htmlmouse__lock_8h__incl.pngnamespacemembers_enum.htmlnamespacemembers_eval.htmlnamespacepp.htmlnamespacepp_1_1ext.htmlnamespacepp_1_1internal.htmlnet__address_8h.htmlnet__address_8h__incl.pngnetwork__list_8h.htmlnetwork__list_8h__incl.pngnetwork__monitor_8h.htmlnetwork__monitor_8h__incl.pngnetwork__proxy_8h.htmlnetwork__proxy_8h__incl.pngpass__ref_8h.htmlpoint_8h.htmlpoint_8h__incl.pngrect_8h.htmlrect_8h__incl.pngresource_8h.htmlresource_8h__incl.pngsize_8h.htmlsize_8h__incl.pngstructpp_1_1_var_1_1_dont_manage.htmlstructpp_1_1_var_1_1_null.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4-members.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper-members.htmlstructpp_1_1internal_1_1_type_unwrapper.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4.htmltcp__socket_8h.htmltcp__socket_8h__incl.pngtext__input__controller_8h.htmltext__input__controller_8h__incl.pngtouch__point_8h.htmltouch__point_8h__incl.pngudp__socket_8h.htmludp__socket_8h__incl.pngurl__loader_8h.htmlurl__loader_8h__incl.pngurl__request__info_8h.htmlurl__request__info_8h__incl.pngurl__response__info_8h.htmlurl__response__info_8h__incl.pngvar_8h.htmlvar_8h__incl.pngvar__array_8h.htmlvar__array_8h__incl.pngvar__array__buffer_8h.htmlvar__array__buffer_8h__incl.pngvar__dictionary_8h.htmlvar__dictionary_8h__incl.pngview_8h.htmlview_8h__incl.pngwebsocket_8h.htmlwebsocket_8h__incl.png
index.html
pepper_dev
c
globals_defs.htmlgroup___enums.htmlgroup___functions.htmlgroup___interfaces.htmlgroup___structs.htmlgroup___typedefs.htmlindex.htmlindex.rstpp__array__output_8h.htmlpp__array__output_8h__incl.pngpp__bool_8h.htmlpp__bool_8h__incl.pngpp__completion__callback_8h.htmlpp__completion__callback_8h__incl.pngpp__directory__entry_8h.htmlpp__directory__entry_8h__incl.pngpp__errors_8h.htmlpp__errors_8h__incl.pngpp__file__info_8h.htmlpp__file__info_8h__incl.pngpp__graphics__3d_8h.htmlpp__graphics__3d_8h__incl.pngpp__input__event_8h.htmlpp__input__event_8h__incl.pngpp__instance_8h.htmlpp__instance_8h__incl.pngpp__module_8h.htmlpp__module_8h__incl.pngpp__point_8h.htmlpp__point_8h__incl.pngpp__rect_8h.htmlpp__rect_8h__incl.pngpp__resource_8h.htmlpp__resource_8h__incl.pngpp__size_8h.htmlpp__size_8h__incl.pngpp__stdint_8h.htmlpp__stdint_8h__incl.pngpp__time_8h.htmlpp__time_8h__incl.pngpp__touch__point_8h.htmlpp__touch__point_8h__incl.pngpp__var_8h.htmlpp__var_8h__incl.pngppb_8h.htmlppb_8h__incl.pngppb__audio_8h.htmlppb__audio_8h__incl.pngppb__audio__config_8h.htmlppb__audio__config_8h__incl.pngppb__audio__frame_8h.htmlppb__audio__frame_8h__incl.pngppb__console_8h.htmlppb__console_8h__incl.pngppb__core_8h.htmlppb__core_8h__incl.pngppb__file__io_8h.htmlppb__file__io_8h__incl.pngppb__file__ref_8h.htmlppb__file__ref_8h__incl.pngppb__file__system_8h.htmlppb__file__system_8h__incl.pngppb__fullscreen_8h.htmlppb__fullscreen_8h__incl.pngppb__gamepad_8h.htmlppb__gamepad_8h__incl.pngppb__graphics__2d_8h.htmlppb__graphics__2d_8h__incl.pngppb__graphics__3d_8h.htmlppb__graphics__3d_8h__incl.pngppb__host__resolver_8h.htmlppb__host__resolver_8h__incl.pngppb__image__data_8h.htmlppb__image__data_8h__incl.pngppb__input__event_8h.htmlppb__input__event_8h__incl.pngppb__instance_8h.htmlppb__instance_8h__incl.pngppb__media__stream__audio__track_8h.htmlppb__media__stream__audio__track_8h__incl.pngppb__media__stream__video__track_8h.htmlppb__media__stream__video__track_8h__incl.pngppb__message__loop_8h.htmlppb__message__loop_8h__incl.pngppb__messaging_8h.htmlppb__messaging_8h__incl.pngppb__mouse__cursor_8h.htmlppb__mouse__cursor_8h__incl.pngppb__mouse__lock_8h.htmlppb__mouse__lock_8h__incl.pngppb__net__address_8h.htmlppb__net__address_8h__incl.pngppb__network__list_8h.htmlppb__network__list_8h__incl.pngppb__network__monitor_8h.htmlppb__network__monitor_8h__incl.pngppb__network__proxy_8h.htmlppb__network__proxy_8h__incl.pngppb__tcp__socket_8h.htmlppb__tcp__socket_8h__incl.pngppb__text__input__controller_8h.htmlppb__text__input__controller_8h__incl.pngppb__udp__socket_8h.htmlppb__udp__socket_8h__incl.pngppb__url__loader_8h.htmlppb__url__loader_8h__incl.pngppb__url__request__info_8h.htmlppb__url__request__info_8h__incl.pngppb__url__response__info_8h.htmlppb__url__response__info_8h__incl.pngppb__var_8h.htmlppb__var_8h__incl.pngppb__var__array_8h.htmlppb__var__array_8h__incl.pngppb__var__array__buffer_8h.htmlppb__var__array__buffer_8h__incl.pngppb__var__dictionary_8h.htmlppb__var__dictionary_8h__incl.pngppb__video__frame_8h.htmlppb__video__frame_8h__incl.pngppb__view_8h.htmlppb__view_8h__incl.pngppb__websocket_8h.htmlppb__websocket_8h__incl.pngppp_8h.htmlppp_8h__incl.pngppp__graphics__3d_8h.htmlppp__graphics__3d_8h__incl.pngppp__input__event_8h.htmlppp__input__event_8h__incl.pngppp__instance_8h.htmlppp__instance_8h__incl.pngppp__messaging_8h.htmlppp__messaging_8h__incl.pngppp__mouse__lock_8h.htmlppp__mouse__lock_8h__incl.pngstruct_p_p___array_output.htmlstruct_p_p___completion_callback.htmlstruct_p_p___directory_entry.htmlstruct_p_p___file_info.htmlstruct_p_p___float_point.htmlstruct_p_p___gamepad_sample_data.htmlstruct_p_p___gamepads_sample_data.htmlstruct_p_p___host_resolver___hint.htmlstruct_p_p___image_data_desc.htmlstruct_p_p___input_event___character.htmlstruct_p_p___input_event___key.htmlstruct_p_p___input_event___mouse.htmlstruct_p_p___input_event___wheel.htmlstruct_p_p___net_address___i_pv4.htmlstruct_p_p___net_address___i_pv6.htmlstruct_p_p___point.htmlstruct_p_p___rect.htmlstruct_p_p___size.htmlstruct_p_p___touch_point.htmlstruct_p_p___var.htmlstruct_p_p_b___audio__1__1.htmlstruct_p_p_b___audio_config__1__1.htmlstruct_p_p_b___audio_frame__0__1.htmlstruct_p_p_b___console__1__0.htmlstruct_p_p_b___core__1__0.htmlstruct_p_p_b___file_i_o__1__1.htmlstruct_p_p_b___file_ref__1__2.htmlstruct_p_p_b___file_system__1__0.htmlstruct_p_p_b___fullscreen__1__0.htmlstruct_p_p_b___gamepad__1__0.htmlstruct_p_p_b___graphics2_d__1__1.htmlstruct_p_p_b___graphics3_d__1__0.htmlstruct_p_p_b___host_resolver__1__0.htmlstruct_p_p_b___i_m_e_input_event__1__0.htmlstruct_p_p_b___image_data__1__0.htmlstruct_p_p_b___input_event__1__0.htmlstruct_p_p_b___instance__1__0.htmlstruct_p_p_b___keyboard_input_event__1__0.htmlstruct_p_p_b___media_stream_audio_track__0__1.htmlstruct_p_p_b___media_stream_video_track__0__1.htmlstruct_p_p_b___message_loop__1__0.htmlstruct_p_p_b___messaging__1__0.htmlstruct_p_p_b___mouse_cursor__1__0.htmlstruct_p_p_b___mouse_input_event__1__1.htmlstruct_p_p_b___mouse_lock__1__0.htmlstruct_p_p_b___net_address__1__0.htmlstruct_p_p_b___network_list__1__0.htmlstruct_p_p_b___network_monitor__1__0.htmlstruct_p_p_b___network_proxy__1__0.htmlstruct_p_p_b___t_c_p_socket__1__1.htmlstruct_p_p_b___text_input_controller__1__0.htmlstruct_p_p_b___touch_input_event__1__0.htmlstruct_p_p_b___u_d_p_socket__1__0.htmlstruct_p_p_b___u_r_l_loader__1__0.htmlstruct_p_p_b___u_r_l_request_info__1__0.htmlstruct_p_p_b___u_r_l_response_info__1__0.htmlstruct_p_p_b___var__1__1.htmlstruct_p_p_b___var_array__1__0.htmlstruct_p_p_b___var_array_buffer__1__0.htmlstruct_p_p_b___var_dictionary__1__0.htmlstruct_p_p_b___video_frame__0__1.htmlstruct_p_p_b___view__1__1.htmlstruct_p_p_b___web_socket__1__0.htmlstruct_p_p_b___wheel_input_event__1__0.htmlstruct_p_p_p___graphics3_d__1__0.htmlstruct_p_p_p___input_event__0__1.htmlstruct_p_p_p___instance__1__1.htmlstruct_p_p_p___messaging__1__0.htmlstruct_p_p_p___mouse_lock__1__0.htmlunion_p_p___var_value.html
cpp
audio_8h.htmlaudio_8h__incl.pngaudio__config_8h.htmlaudio__config_8h__incl.pngaudio__frame_8h.htmlaudio__frame_8h__incl.pngclasspp_1_1_audio-members.htmlclasspp_1_1_audio.htmlclasspp_1_1_audio__inherit__graph.pngclasspp_1_1_audio_config-members.htmlclasspp_1_1_audio_config.htmlclasspp_1_1_audio_config__inherit__graph.pngclasspp_1_1_audio_frame-members.htmlclasspp_1_1_audio_frame.htmlclasspp_1_1_audio_frame__inherit__graph.pngclasspp_1_1_completion_callback-members.htmlclasspp_1_1_completion_callback.htmlclasspp_1_1_completion_callback__inherit__graph.pngclasspp_1_1_completion_callback_factory-members.htmlclasspp_1_1_completion_callback_factory.htmlclasspp_1_1_completion_callback_with_output-members.htmlclasspp_1_1_completion_callback_with_output.htmlclasspp_1_1_completion_callback_with_output__inherit__graph.pngclasspp_1_1_core-members.htmlclasspp_1_1_core.htmlclasspp_1_1_directory_entry-members.htmlclasspp_1_1_directory_entry.htmlclasspp_1_1_file_i_o-members.htmlclasspp_1_1_file_i_o.htmlclasspp_1_1_file_i_o__inherit__graph.pngclasspp_1_1_file_ref-members.htmlclasspp_1_1_file_ref.htmlclasspp_1_1_file_ref__inherit__graph.pngclasspp_1_1_file_system-members.htmlclasspp_1_1_file_system.htmlclasspp_1_1_file_system__inherit__graph.pngclasspp_1_1_float_point-members.htmlclasspp_1_1_float_point.htmlclasspp_1_1_fullscreen-members.htmlclasspp_1_1_fullscreen.htmlclasspp_1_1_graphics2_d-members.htmlclasspp_1_1_graphics2_d.htmlclasspp_1_1_graphics2_d__inherit__graph.pngclasspp_1_1_graphics3_d-members.htmlclasspp_1_1_graphics3_d.htmlclasspp_1_1_graphics3_d__inherit__graph.pngclasspp_1_1_graphics3_d_client-members.htmlclasspp_1_1_graphics3_d_client.htmlclasspp_1_1_host_resolver-members.htmlclasspp_1_1_host_resolver.htmlclasspp_1_1_host_resolver__inherit__graph.pngclasspp_1_1_i_m_e_input_event-members.htmlclasspp_1_1_i_m_e_input_event.htmlclasspp_1_1_i_m_e_input_event__inherit__graph.pngclasspp_1_1_image_data-members.htmlclasspp_1_1_image_data.htmlclasspp_1_1_image_data__inherit__graph.pngclasspp_1_1_input_event-members.htmlclasspp_1_1_input_event.htmlclasspp_1_1_input_event__inherit__graph.pngclasspp_1_1_instance-members.htmlclasspp_1_1_instance.htmlclasspp_1_1_instance_handle-members.htmlclasspp_1_1_instance_handle.htmlclasspp_1_1_keyboard_input_event-members.htmlclasspp_1_1_keyboard_input_event.htmlclasspp_1_1_keyboard_input_event__inherit__graph.pngclasspp_1_1_media_stream_audio_track-members.htmlclasspp_1_1_media_stream_audio_track.htmlclasspp_1_1_media_stream_audio_track__inherit__graph.pngclasspp_1_1_media_stream_video_track-members.htmlclasspp_1_1_media_stream_video_track.htmlclasspp_1_1_media_stream_video_track__inherit__graph.pngclasspp_1_1_message_loop-members.htmlclasspp_1_1_message_loop.htmlclasspp_1_1_message_loop__inherit__graph.pngclasspp_1_1_module-members.htmlclasspp_1_1_module.htmlclasspp_1_1_mouse_cursor-members.htmlclasspp_1_1_mouse_cursor.htmlclasspp_1_1_mouse_input_event-members.htmlclasspp_1_1_mouse_input_event.htmlclasspp_1_1_mouse_input_event__inherit__graph.pngclasspp_1_1_mouse_lock-members.htmlclasspp_1_1_mouse_lock.htmlclasspp_1_1_net_address-members.htmlclasspp_1_1_net_address.htmlclasspp_1_1_net_address__inherit__graph.pngclasspp_1_1_network_list-members.htmlclasspp_1_1_network_list.htmlclasspp_1_1_network_list__inherit__graph.pngclasspp_1_1_network_monitor-members.htmlclasspp_1_1_network_monitor.htmlclasspp_1_1_network_monitor__inherit__graph.pngclasspp_1_1_network_proxy-members.htmlclasspp_1_1_network_proxy.htmlclasspp_1_1_point-members.htmlclasspp_1_1_point.htmlclasspp_1_1_rect-members.htmlclasspp_1_1_rect.htmlclasspp_1_1_resource-members.htmlclasspp_1_1_resource.htmlclasspp_1_1_resource__inherit__graph.pngclasspp_1_1_size-members.htmlclasspp_1_1_size.htmlclasspp_1_1_t_c_p_socket-members.htmlclasspp_1_1_t_c_p_socket.htmlclasspp_1_1_t_c_p_socket__inherit__graph.pngclasspp_1_1_text_input_controller-members.htmlclasspp_1_1_text_input_controller.htmlclasspp_1_1_touch_input_event-members.htmlclasspp_1_1_touch_input_event.htmlclasspp_1_1_touch_input_event__inherit__graph.pngclasspp_1_1_touch_point-members.htmlclasspp_1_1_touch_point.htmlclasspp_1_1_u_d_p_socket-members.htmlclasspp_1_1_u_d_p_socket.htmlclasspp_1_1_u_d_p_socket__inherit__graph.pngclasspp_1_1_u_r_l_loader-members.htmlclasspp_1_1_u_r_l_loader.htmlclasspp_1_1_u_r_l_loader__inherit__graph.pngclasspp_1_1_u_r_l_request_info-members.htmlclasspp_1_1_u_r_l_request_info.htmlclasspp_1_1_u_r_l_request_info__inherit__graph.pngclasspp_1_1_u_r_l_response_info-members.htmlclasspp_1_1_u_r_l_response_info.htmlclasspp_1_1_u_r_l_response_info__inherit__graph.pngclasspp_1_1_var-members.htmlclasspp_1_1_var.htmlclasspp_1_1_var_1_1_out_exception-members.htmlclasspp_1_1_var_1_1_out_exception.htmlclasspp_1_1_var__inherit__graph.pngclasspp_1_1_var_array-members.htmlclasspp_1_1_var_array.htmlclasspp_1_1_var_array__inherit__graph.pngclasspp_1_1_var_array_buffer-members.htmlclasspp_1_1_var_array_buffer.htmlclasspp_1_1_var_array_buffer__inherit__graph.pngclasspp_1_1_var_dictionary-members.htmlclasspp_1_1_var_dictionary.htmlclasspp_1_1_var_dictionary__inherit__graph.pngclasspp_1_1_video_frame-members.htmlclasspp_1_1_video_frame.htmlclasspp_1_1_video_frame__inherit__graph.pngclasspp_1_1_view-members.htmlclasspp_1_1_view.htmlclasspp_1_1_view__inherit__graph.pngclasspp_1_1_web_socket-members.htmlclasspp_1_1_web_socket.htmlclasspp_1_1_web_socket__inherit__graph.pngclasspp_1_1_wheel_input_event-members.htmlclasspp_1_1_wheel_input_event.htmlclasspp_1_1_wheel_input_event__inherit__graph.pngclasspp_1_1ext_1_1_ext_completion_callback_with_output-members.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output__inherit__graph.pngclasspp_1_1internal_1_1_completion_callback_with_output_base-members.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base__inherit__graph.pngclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage-members.htmlclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage.htmlcompletion__callback_8h.htmlcompletion__callback_8h__incl.pngcompletion__callback__factory_8h.htmlcompletion__callback__factory_8h__incl.pngcore_8h.htmlcore_8h__incl.pngdirectory__entry_8h.htmldirectory__entry_8h__incl.pngfile__io_8h.htmlfile__io_8h__incl.pngfile__ref_8h.htmlfile__ref_8h__incl.pngfile__system_8h.htmlfile__system_8h__incl.pngfullscreen_8h.htmlfullscreen_8h__incl.pngglobals_defs.htmlgraphics__2d_8h.htmlgraphics__2d_8h__incl.pnggraphics__3d_8h.htmlgraphics__3d_8h__incl.pnggraphics__3d__client_8h.htmlgraphics__3d__client_8h__incl.pnghost__resolver_8h.htmlhost__resolver_8h__incl.pngimage__data_8h.htmlimage__data_8h__incl.pngindex.htmlindex.rstinherit_graph_0.pnginherit_graph_1.pnginherit_graph_10.pnginherit_graph_11.pnginherit_graph_12.pnginherit_graph_13.pnginherit_graph_14.pnginherit_graph_15.pnginherit_graph_16.pnginherit_graph_17.pnginherit_graph_18.pnginherit_graph_19.pnginherit_graph_2.pnginherit_graph_20.pnginherit_graph_21.pnginherit_graph_22.pnginherit_graph_23.pnginherit_graph_24.pnginherit_graph_25.pnginherit_graph_26.pnginherit_graph_27.pnginherit_graph_3.pnginherit_graph_4.pnginherit_graph_5.pnginherit_graph_6.pnginherit_graph_7.pnginherit_graph_8.pnginherit_graph_9.pnginherits.htmlinput__event_8h.htmlinput__event_8h__incl.pnginstance_8h.htmlinstance_8h__incl.pnginstance__handle_8h.htmlinstance__handle_8h__incl.pnglogging_8h.htmllogging_8h__incl.pngmedia__stream__audio__track_8h.htmlmedia__stream__audio__track_8h__incl.pngmedia__stream__video__track_8h.htmlmedia__stream__video__track_8h__incl.pngmessage__loop_8h.htmlmessage__loop_8h__incl.pngmodule_8h.htmlmodule_8h__incl.pngmodule__embedder_8h.htmlmodule__embedder_8h__incl.pngmodule__impl_8h.htmlmodule__impl_8h__incl.pngmouse__cursor_8h.htmlmouse__cursor_8h__incl.pngmouse__lock_8h.htmlmouse__lock_8h__incl.pngnamespacemembers_enum.htmlnamespacemembers_eval.htmlnamespacepp.htmlnamespacepp_1_1ext.htmlnamespacepp_1_1internal.htmlnet__address_8h.htmlnet__address_8h__incl.pngnetwork__list_8h.htmlnetwork__list_8h__incl.pngnetwork__monitor_8h.htmlnetwork__monitor_8h__incl.pngnetwork__proxy_8h.htmlnetwork__proxy_8h__incl.pngpass__ref_8h.htmlpoint_8h.htmlpoint_8h__incl.pngrect_8h.htmlrect_8h__incl.pngresource_8h.htmlresource_8h__incl.pngsize_8h.htmlsize_8h__incl.pngstructpp_1_1_var_1_1_dont_manage.htmlstructpp_1_1_var_1_1_null.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4-members.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper-members.htmlstructpp_1_1internal_1_1_type_unwrapper.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4.htmltcp__socket_8h.htmltcp__socket_8h__incl.pngtext__input__controller_8h.htmltext__input__controller_8h__incl.pngtouch__point_8h.htmltouch__point_8h__incl.pngudp__socket_8h.htmludp__socket_8h__incl.pngurl__loader_8h.htmlurl__loader_8h__incl.pngurl__request__info_8h.htmlurl__request__info_8h__incl.pngurl__response__info_8h.htmlurl__response__info_8h__incl.pngvar_8h.htmlvar_8h__incl.pngvar__array_8h.htmlvar__array_8h__incl.pngvar__array__buffer_8h.htmlvar__array__buffer_8h__incl.pngvar__dictionary_8h.htmlvar__dictionary_8h__incl.pngvideo__frame_8h.htmlvideo__frame_8h__incl.pngview_8h.htmlview_8h__incl.pngwebsocket_8h.htmlwebsocket_8h__incl.png
index.html
pepper_stable
c
globals_defs.htmlgroup___enums.htmlgroup___functions.htmlgroup___interfaces.htmlgroup___structs.htmlgroup___typedefs.htmlindex.htmlindex.rstpp__array__output_8h.htmlpp__array__output_8h__incl.pngpp__bool_8h.htmlpp__bool_8h__incl.pngpp__completion__callback_8h.htmlpp__completion__callback_8h__incl.pngpp__directory__entry_8h.htmlpp__directory__entry_8h__incl.pngpp__errors_8h.htmlpp__errors_8h__incl.pngpp__file__info_8h.htmlpp__file__info_8h__incl.pngpp__graphics__3d_8h.htmlpp__graphics__3d_8h__incl.pngpp__input__event_8h.htmlpp__input__event_8h__incl.pngpp__instance_8h.htmlpp__instance_8h__incl.pngpp__module_8h.htmlpp__module_8h__incl.pngpp__point_8h.htmlpp__point_8h__incl.pngpp__rect_8h.htmlpp__rect_8h__incl.pngpp__resource_8h.htmlpp__resource_8h__incl.pngpp__size_8h.htmlpp__size_8h__incl.pngpp__stdint_8h.htmlpp__stdint_8h__incl.pngpp__time_8h.htmlpp__time_8h__incl.pngpp__touch__point_8h.htmlpp__touch__point_8h__incl.pngpp__var_8h.htmlpp__var_8h__incl.pngppb_8h.htmlppb_8h__incl.pngppb__audio_8h.htmlppb__audio_8h__incl.pngppb__audio__config_8h.htmlppb__audio__config_8h__incl.pngppb__console_8h.htmlppb__console_8h__incl.pngppb__core_8h.htmlppb__core_8h__incl.pngppb__file__io_8h.htmlppb__file__io_8h__incl.pngppb__file__ref_8h.htmlppb__file__ref_8h__incl.pngppb__file__system_8h.htmlppb__file__system_8h__incl.pngppb__fullscreen_8h.htmlppb__fullscreen_8h__incl.pngppb__gamepad_8h.htmlppb__gamepad_8h__incl.pngppb__graphics__2d_8h.htmlppb__graphics__2d_8h__incl.pngppb__graphics__3d_8h.htmlppb__graphics__3d_8h__incl.pngppb__host__resolver_8h.htmlppb__host__resolver_8h__incl.pngppb__image__data_8h.htmlppb__image__data_8h__incl.pngppb__input__event_8h.htmlppb__input__event_8h__incl.pngppb__instance_8h.htmlppb__instance_8h__incl.pngppb__message__loop_8h.htmlppb__message__loop_8h__incl.pngppb__messaging_8h.htmlppb__messaging_8h__incl.pngppb__mouse__cursor_8h.htmlppb__mouse__cursor_8h__incl.pngppb__mouse__lock_8h.htmlppb__mouse__lock_8h__incl.pngppb__net__address_8h.htmlppb__net__address_8h__incl.pngppb__network__list_8h.htmlppb__network__list_8h__incl.pngppb__network__monitor_8h.htmlppb__network__monitor_8h__incl.pngppb__network__proxy_8h.htmlppb__network__proxy_8h__incl.pngppb__tcp__socket_8h.htmlppb__tcp__socket_8h__incl.pngppb__text__input__controller_8h.htmlppb__text__input__controller_8h__incl.pngppb__udp__socket_8h.htmlppb__udp__socket_8h__incl.pngppb__url__loader_8h.htmlppb__url__loader_8h__incl.pngppb__url__request__info_8h.htmlppb__url__request__info_8h__incl.pngppb__url__response__info_8h.htmlppb__url__response__info_8h__incl.pngppb__var_8h.htmlppb__var_8h__incl.pngppb__var__array_8h.htmlppb__var__array_8h__incl.pngppb__var__array__buffer_8h.htmlppb__var__array__buffer_8h__incl.pngppb__var__dictionary_8h.htmlppb__var__dictionary_8h__incl.pngppb__view_8h.htmlppb__view_8h__incl.pngppb__websocket_8h.htmlppb__websocket_8h__incl.pngppp_8h.htmlppp_8h__incl.pngppp__graphics__3d_8h.htmlppp__graphics__3d_8h__incl.pngppp__input__event_8h.htmlppp__input__event_8h__incl.pngppp__instance_8h.htmlppp__instance_8h__incl.pngppp__messaging_8h.htmlppp__messaging_8h__incl.pngppp__mouse__lock_8h.htmlppp__mouse__lock_8h__incl.pngstruct_p_p___array_output.htmlstruct_p_p___completion_callback.htmlstruct_p_p___directory_entry.htmlstruct_p_p___file_info.htmlstruct_p_p___float_point.htmlstruct_p_p___gamepad_sample_data.htmlstruct_p_p___gamepads_sample_data.htmlstruct_p_p___host_resolver___hint.htmlstruct_p_p___image_data_desc.htmlstruct_p_p___input_event___character.htmlstruct_p_p___input_event___key.htmlstruct_p_p___input_event___mouse.htmlstruct_p_p___input_event___wheel.htmlstruct_p_p___net_address___i_pv4.htmlstruct_p_p___net_address___i_pv6.htmlstruct_p_p___point.htmlstruct_p_p___rect.htmlstruct_p_p___size.htmlstruct_p_p___touch_point.htmlstruct_p_p___var.htmlstruct_p_p_b___audio__1__1.htmlstruct_p_p_b___audio_config__1__1.htmlstruct_p_p_b___console__1__0.htmlstruct_p_p_b___core__1__0.htmlstruct_p_p_b___file_i_o__1__1.htmlstruct_p_p_b___file_ref__1__1.htmlstruct_p_p_b___file_system__1__0.htmlstruct_p_p_b___fullscreen__1__0.htmlstruct_p_p_b___gamepad__1__0.htmlstruct_p_p_b___graphics2_d__1__1.htmlstruct_p_p_b___graphics3_d__1__0.htmlstruct_p_p_b___host_resolver__1__0.htmlstruct_p_p_b___i_m_e_input_event__1__0.htmlstruct_p_p_b___image_data__1__0.htmlstruct_p_p_b___input_event__1__0.htmlstruct_p_p_b___instance__1__0.htmlstruct_p_p_b___keyboard_input_event__1__0.htmlstruct_p_p_b___message_loop__1__0.htmlstruct_p_p_b___messaging__1__0.htmlstruct_p_p_b___mouse_cursor__1__0.htmlstruct_p_p_b___mouse_input_event__1__1.htmlstruct_p_p_b___mouse_lock__1__0.htmlstruct_p_p_b___net_address__1__0.htmlstruct_p_p_b___network_list__1__0.htmlstruct_p_p_b___network_monitor__1__0.htmlstruct_p_p_b___network_proxy__1__0.htmlstruct_p_p_b___t_c_p_socket__1__1.htmlstruct_p_p_b___text_input_controller__1__0.htmlstruct_p_p_b___touch_input_event__1__0.htmlstruct_p_p_b___u_d_p_socket__1__0.htmlstruct_p_p_b___u_r_l_loader__1__0.htmlstruct_p_p_b___u_r_l_request_info__1__0.htmlstruct_p_p_b___u_r_l_response_info__1__0.htmlstruct_p_p_b___var__1__1.htmlstruct_p_p_b___var_array__1__0.htmlstruct_p_p_b___var_array_buffer__1__0.htmlstruct_p_p_b___var_dictionary__1__0.htmlstruct_p_p_b___view__1__1.htmlstruct_p_p_b___web_socket__1__0.htmlstruct_p_p_b___wheel_input_event__1__0.htmlstruct_p_p_p___graphics3_d__1__0.htmlstruct_p_p_p___input_event__0__1.htmlstruct_p_p_p___instance__1__1.htmlstruct_p_p_p___messaging__1__0.htmlstruct_p_p_p___mouse_lock__1__0.htmlunion_p_p___var_value.html
cpp
audio_8h.htmlaudio_8h__incl.pngaudio__config_8h.htmlaudio__config_8h__incl.pngclasspp_1_1_audio-members.htmlclasspp_1_1_audio.htmlclasspp_1_1_audio__inherit__graph.pngclasspp_1_1_audio_config-members.htmlclasspp_1_1_audio_config.htmlclasspp_1_1_audio_config__inherit__graph.pngclasspp_1_1_completion_callback-members.htmlclasspp_1_1_completion_callback.htmlclasspp_1_1_completion_callback__inherit__graph.pngclasspp_1_1_completion_callback_factory-members.htmlclasspp_1_1_completion_callback_factory.htmlclasspp_1_1_completion_callback_with_output-members.htmlclasspp_1_1_completion_callback_with_output.htmlclasspp_1_1_completion_callback_with_output__inherit__graph.pngclasspp_1_1_core-members.htmlclasspp_1_1_core.htmlclasspp_1_1_directory_entry-members.htmlclasspp_1_1_directory_entry.htmlclasspp_1_1_file_i_o-members.htmlclasspp_1_1_file_i_o.htmlclasspp_1_1_file_i_o__inherit__graph.pngclasspp_1_1_file_ref-members.htmlclasspp_1_1_file_ref.htmlclasspp_1_1_file_ref__inherit__graph.pngclasspp_1_1_file_system-members.htmlclasspp_1_1_file_system.htmlclasspp_1_1_file_system__inherit__graph.pngclasspp_1_1_float_point-members.htmlclasspp_1_1_float_point.htmlclasspp_1_1_fullscreen-members.htmlclasspp_1_1_fullscreen.htmlclasspp_1_1_graphics2_d-members.htmlclasspp_1_1_graphics2_d.htmlclasspp_1_1_graphics2_d__inherit__graph.pngclasspp_1_1_graphics3_d-members.htmlclasspp_1_1_graphics3_d.htmlclasspp_1_1_graphics3_d__inherit__graph.pngclasspp_1_1_graphics3_d_client-members.htmlclasspp_1_1_graphics3_d_client.htmlclasspp_1_1_host_resolver-members.htmlclasspp_1_1_host_resolver.htmlclasspp_1_1_host_resolver__inherit__graph.pngclasspp_1_1_i_m_e_input_event-members.htmlclasspp_1_1_i_m_e_input_event.htmlclasspp_1_1_i_m_e_input_event__inherit__graph.pngclasspp_1_1_image_data-members.htmlclasspp_1_1_image_data.htmlclasspp_1_1_image_data__inherit__graph.pngclasspp_1_1_input_event-members.htmlclasspp_1_1_input_event.htmlclasspp_1_1_input_event__inherit__graph.pngclasspp_1_1_instance-members.htmlclasspp_1_1_instance.htmlclasspp_1_1_instance_handle-members.htmlclasspp_1_1_instance_handle.htmlclasspp_1_1_keyboard_input_event-members.htmlclasspp_1_1_keyboard_input_event.htmlclasspp_1_1_keyboard_input_event__inherit__graph.pngclasspp_1_1_message_loop-members.htmlclasspp_1_1_message_loop.htmlclasspp_1_1_message_loop__inherit__graph.pngclasspp_1_1_module-members.htmlclasspp_1_1_module.htmlclasspp_1_1_mouse_cursor-members.htmlclasspp_1_1_mouse_cursor.htmlclasspp_1_1_mouse_input_event-members.htmlclasspp_1_1_mouse_input_event.htmlclasspp_1_1_mouse_input_event__inherit__graph.pngclasspp_1_1_mouse_lock-members.htmlclasspp_1_1_mouse_lock.htmlclasspp_1_1_net_address-members.htmlclasspp_1_1_net_address.htmlclasspp_1_1_net_address__inherit__graph.pngclasspp_1_1_network_list-members.htmlclasspp_1_1_network_list.htmlclasspp_1_1_network_list__inherit__graph.pngclasspp_1_1_network_monitor-members.htmlclasspp_1_1_network_monitor.htmlclasspp_1_1_network_monitor__inherit__graph.pngclasspp_1_1_network_proxy-members.htmlclasspp_1_1_network_proxy.htmlclasspp_1_1_point-members.htmlclasspp_1_1_point.htmlclasspp_1_1_rect-members.htmlclasspp_1_1_rect.htmlclasspp_1_1_resource-members.htmlclasspp_1_1_resource.htmlclasspp_1_1_resource__inherit__graph.pngclasspp_1_1_size-members.htmlclasspp_1_1_size.htmlclasspp_1_1_t_c_p_socket-members.htmlclasspp_1_1_t_c_p_socket.htmlclasspp_1_1_t_c_p_socket__inherit__graph.pngclasspp_1_1_text_input_controller-members.htmlclasspp_1_1_text_input_controller.htmlclasspp_1_1_touch_input_event-members.htmlclasspp_1_1_touch_input_event.htmlclasspp_1_1_touch_input_event__inherit__graph.pngclasspp_1_1_touch_point-members.htmlclasspp_1_1_touch_point.htmlclasspp_1_1_u_d_p_socket-members.htmlclasspp_1_1_u_d_p_socket.htmlclasspp_1_1_u_d_p_socket__inherit__graph.pngclasspp_1_1_u_r_l_loader-members.htmlclasspp_1_1_u_r_l_loader.htmlclasspp_1_1_u_r_l_loader__inherit__graph.pngclasspp_1_1_u_r_l_request_info-members.htmlclasspp_1_1_u_r_l_request_info.htmlclasspp_1_1_u_r_l_request_info__inherit__graph.pngclasspp_1_1_u_r_l_response_info-members.htmlclasspp_1_1_u_r_l_response_info.htmlclasspp_1_1_u_r_l_response_info__inherit__graph.pngclasspp_1_1_var-members.htmlclasspp_1_1_var.htmlclasspp_1_1_var_1_1_out_exception-members.htmlclasspp_1_1_var_1_1_out_exception.htmlclasspp_1_1_var__inherit__graph.pngclasspp_1_1_var_array-members.htmlclasspp_1_1_var_array.htmlclasspp_1_1_var_array__inherit__graph.pngclasspp_1_1_var_array_buffer-members.htmlclasspp_1_1_var_array_buffer.htmlclasspp_1_1_var_array_buffer__inherit__graph.pngclasspp_1_1_var_dictionary-members.htmlclasspp_1_1_var_dictionary.htmlclasspp_1_1_var_dictionary__inherit__graph.pngclasspp_1_1_view-members.htmlclasspp_1_1_view.htmlclasspp_1_1_view__inherit__graph.pngclasspp_1_1_web_socket-members.htmlclasspp_1_1_web_socket.htmlclasspp_1_1_web_socket__inherit__graph.pngclasspp_1_1_wheel_input_event-members.htmlclasspp_1_1_wheel_input_event.htmlclasspp_1_1_wheel_input_event__inherit__graph.pngclasspp_1_1ext_1_1_ext_completion_callback_with_output-members.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output.htmlclasspp_1_1ext_1_1_ext_completion_callback_with_output__inherit__graph.pngclasspp_1_1internal_1_1_completion_callback_with_output_base-members.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base.htmlclasspp_1_1internal_1_1_completion_callback_with_output_base__inherit__graph.pngclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage-members.htmlclasspp_1_1internal_1_1_directory_entry_array_output_adapter_with_storage.htmlcompletion__callback_8h.htmlcompletion__callback_8h__incl.pngcompletion__callback__factory_8h.htmlcompletion__callback__factory_8h__incl.pngcore_8h.htmlcore_8h__incl.pngdirectory__entry_8h.htmldirectory__entry_8h__incl.pngfile__io_8h.htmlfile__io_8h__incl.pngfile__ref_8h.htmlfile__ref_8h__incl.pngfile__system_8h.htmlfile__system_8h__incl.pngfullscreen_8h.htmlfullscreen_8h__incl.pngglobals_defs.htmlgraphics__2d_8h.htmlgraphics__2d_8h__incl.pnggraphics__3d_8h.htmlgraphics__3d_8h__incl.pnggraphics__3d__client_8h.htmlgraphics__3d__client_8h__incl.pnghost__resolver_8h.htmlhost__resolver_8h__incl.pngimage__data_8h.htmlimage__data_8h__incl.pngindex.htmlindex.rstinherit_graph_0.pnginherit_graph_1.pnginherit_graph_10.pnginherit_graph_11.pnginherit_graph_12.pnginherit_graph_13.pnginherit_graph_14.pnginherit_graph_15.pnginherit_graph_16.pnginherit_graph_17.pnginherit_graph_18.pnginherit_graph_19.pnginherit_graph_2.pnginherit_graph_20.pnginherit_graph_21.pnginherit_graph_22.pnginherit_graph_23.pnginherit_graph_24.pnginherit_graph_25.pnginherit_graph_26.pnginherit_graph_27.pnginherit_graph_3.pnginherit_graph_4.pnginherit_graph_5.pnginherit_graph_6.pnginherit_graph_7.pnginherit_graph_8.pnginherit_graph_9.pnginherits.htmlinput__event_8h.htmlinput__event_8h__incl.pnginstance_8h.htmlinstance_8h__incl.pnginstance__handle_8h.htmlinstance__handle_8h__incl.pnglogging_8h.htmllogging_8h__incl.pngmessage__loop_8h.htmlmessage__loop_8h__incl.pngmodule_8h.htmlmodule_8h__incl.pngmodule__embedder_8h.htmlmodule__embedder_8h__incl.pngmodule__impl_8h.htmlmodule__impl_8h__incl.pngmouse__cursor_8h.htmlmouse__cursor_8h__incl.pngmouse__lock_8h.htmlmouse__lock_8h__incl.pngnamespacemembers_enum.htmlnamespacemembers_eval.htmlnamespacepp.htmlnamespacepp_1_1ext.htmlnamespacepp_1_1internal.htmlnet__address_8h.htmlnet__address_8h__incl.pngnetwork__list_8h.htmlnetwork__list_8h__incl.pngnetwork__monitor_8h.htmlnetwork__monitor_8h__incl.pngnetwork__proxy_8h.htmlnetwork__proxy_8h__incl.pngpass__ref_8h.htmlpoint_8h.htmlpoint_8h__incl.pngrect_8h.htmlrect_8h__incl.pngresource_8h.htmlresource_8h__incl.pngsize_8h.htmlsize_8h__incl.pngstructpp_1_1_var_1_1_dont_manage.htmlstructpp_1_1_var_1_1_null.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4-members.htmlstructpp_1_1internal_1_1_callback_output_traits_3_01std_1_1vector_3_01_directory_entry_01_4_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper-members.htmlstructpp_1_1internal_1_1_type_unwrapper.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01_t_01_6_01_4.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4-members.htmlstructpp_1_1internal_1_1_type_unwrapper_3_01const_01_t_01_6_01_4.htmltcp__socket_8h.htmltcp__socket_8h__incl.pngtext__input__controller_8h.htmltext__input__controller_8h__incl.pngtouch__point_8h.htmltouch__point_8h__incl.pngudp__socket_8h.htmludp__socket_8h__incl.pngurl__loader_8h.htmlurl__loader_8h__incl.pngurl__request__info_8h.htmlurl__request__info_8h__incl.pngurl__response__info_8h.htmlurl__response__info_8h__incl.pngvar_8h.htmlvar_8h__incl.pngvar__array_8h.htmlvar__array_8h__incl.pngvar__array__buffer_8h.htmlvar__array__buffer_8h__incl.pngvar__dictionary_8h.htmlvar__dictionary_8h__incl.pngview_8h.htmlview_8h__incl.pngwebsocket_8h.htmlwebsocket_8h__incl.png
index.html
publications-and-presentations.htmlquick-start.html
reference
rest-devsite-examples.html
sdk
sitemap.htmlversion.html
src

@@ -0,0 +1,442 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="d-graphics">
<span id="devguide-coding-3d-graphics"></span><h1 id="d-graphics"><span id="devguide-coding-3d-graphics"></span>3D Graphics</h1>
<p>Native Client applications use the <a class="reference external" href="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES 2.0</a> API for 3D rendering. This document
describes how to call the OpenGL ES 2.0 interface in a Native Client module and
how to build an efficient rendering loop. It also explains how to validate GPU
drivers and test for specific GPU capabilities, and provides tips to help ensure
your rendering code runs efficiently.</p>
<aside class="note">
<strong>Note</strong>: 3D drawing and OpenGL are complex topics. This document deals only
with issues directly related to programming in the Native Client
environment. To learn more about OpenGL ES 2.0 itself, see the <a class="reference external" href="http://opengles-book.com/">OpenGL ES 2.0
Programming Guide</a>.
</aside>
<section id="validating-the-client-graphics-platform">
<h2 id="validating-the-client-graphics-platform">Validating the client graphics platform</h2>
<p>Native Client is a software technology that lets you code an application once
and run it on multiple platforms without worrying about the implementation
details on every possible target platform. It&#8217;s difficult to provide the same
support at the hardware level. Graphics hardware comes from many different
manufacturers and is controlled by drivers of varying quality. A particular GPU
driver may not support every OpenGL ES 2.0 feature, and some drivers are known
to have vulnerabilities that can be exploited.</p>
<p>Even if the GPU driver is safe to use, your program should perform a validation
check before you launch your application to ensure that the driver supports all
the features you need.</p>
<section id="vetting-the-driver-in-javascript">
<h3 id="vetting-the-driver-in-javascript">Vetting the driver in JavaScript</h3>
<p>At startup, the application should perform a few additional tests that can be
implemented in JavaScript on its hosting web page. The script that performs
these tests should be included before the module&#8217;s <code>embed</code> tag, and ideally
the <code>embed</code> tag should appear on the hosting page only if these tests succeed.</p>
<p>The first thing to check is whether you can create a graphics context. If you
can, use the context to confirm the existence of any required OpenGL ES 2.0
extensions. You may want to refer to the <a class="reference external" href="http://www.khronos.org/registry/webgl/extensions/">extension registry</a> and include <a class="reference external" href="https://developer.mozilla.org/en-US/docs/WebGL/Using_Extensions">vendor
prefixes</a>
when checking for extensions.</p>
</section><section id="vetting-the-driver-in-native-client">
<h3 id="vetting-the-driver-in-native-client">Vetting the driver in Native Client</h3>
<section id="create-a-context">
<h4 id="create-a-context">Create a context</h4>
<p>Once you&#8217;ve passed the JavaScript validation tests, it&#8217;s safe to add a Native
Client embed tag to the hosting web page and load the module. As part of the
module initialization code, you must create a graphics context for the app by
either creating a C++ <code>Graphics3D</code> object or calling <code>PPB_Graphics3D</code> API
function <code>Create</code>. Don&#8217;t assume this will always succeed; you still might have
problems creating the context. If you are in development mode and can&#8217;t create
the context, try creating a simpler version to see if you&#8217;re asking for an
unsupported feature or exceeding a driver resource limit. Your production code
should always check that the context was created and fail gracefully if that&#8217;s
not the case.</p>
</section><section id="check-for-extensions-and-capabilities">
<h4 id="check-for-extensions-and-capabilities">Check for extensions and capabilities</h4>
<p>Not every GPU supports every extension or has the same amount of texture units,
vertex attributes, etc. On startup, call <code>glGetString(GL_EXTENSIONS)</code> and
check for the extensions and the features you need. For example:</p>
<ul class="small-gap">
<li>If you are using non power-of-2 texture with mipmaps, make sure
<code>GL_OES_texture_npot</code> exists.</li>
<li>If you are using floating point textures, make sure <code>GL_OES_texture_float</code>
exists.</li>
<li>If you are using DXT1, DXT3, or DXT5 textures, make sure the corresponding
extensions <code>EXT_texture_compression_dxt1</code>,
<code>GL_CHROMIUM_texture_compression_dxt3</code>, and
<code>GL_CHROMIUM_texture_compression_dxt5</code> exist.</li>
<li>If you are using the functions <code>glDrawArraysInstancedANGLE</code>,
<code>glDrawElementsInstancedANGLE</code>, <code>glVertexAttribDivisorANGLE</code>, or the PPAPI
interface <code>PPB_OpenGLES2InstancedArrays</code>, make sure the corresponding
extension <code>GL_ANGLE_instanced_arrays</code> exists.</li>
<li>If you are using the function <code>glRenderbufferStorageMultisampleEXT</code>, or the
PPAPI interface <code>PPB_OpenGLES2FramebufferMultisample</code>, make sure the
corresponding extension <code>GL_CHROMIUM_framebuffer_multisample</code> exists.</li>
<li>If you are using the functions <code>glGenQueriesEXT</code>, <code>glDeleteQueriesEXT</code>,
<code>glIsQueryEXT</code>, <code>glBeginQueryEXT</code>, <code>glEndQueryEXT</code>, <code>glGetQueryivEXT</code>,
<code>glGetQueryObjectuivEXT</code>, or the PPAPI interface <code>PPB_OpenGLES2Query</code>,
make sure the corresponding extension <code>GL_EXT_occlusion_query_boolean</code>
exists.</li>
<li>If you are using the functions <code>glMapBufferSubDataCHROMIUM</code>,
<code>glUnmapBufferSubDataCHROMIUM</code>, <code>glMapTexSubImage2DCHROMIUM</code>,
<code>glUnmapTexSubImage2DCHROMIUM</code>, or the PPAPI interface
<code>PPB_OpenGLES2ChromiumMapSub</code>, make sure the corresponding extension
<code>GL_CHROMIUM_map_sub</code> exists.</li>
</ul>
<p>Check for system capabilites with <code>glGetIntegerv</code> and adjust shader programs
as well as texture and vertex data accordingly:</p>
<ul class="small-gap">
<li>If you are using textures in vertex shaders, make sure
<code>glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, ...)</code> and
<code>glGetIntegerv(GL_MAX_TEXTURE_SIZE, ...)</code> return values greater than 0.</li>
<li>If you are using more than 8 textures in a single shader, make sure
<code>glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...)</code> returns a value greater
than or equal to the number of simultaneous textures you need.</li>
</ul>
</section></section><section id="vetting-the-driver-in-the-chrome-web-store">
<h3 id="vetting-the-driver-in-the-chrome-web-store">Vetting the driver in the Chrome Web Store</h3>
<p>If you choose to place your application in the <a class="reference external" href="https://developers.google.com/chrome/web-store/docs/">Chrome Web
Store</a>, its Web Store
<a class="reference external" href="http://code.google.com/chrome/extensions/manifest.html">manifest file</a> can
include the <code>webgl</code> feature in the requirements parameter. It looks like this:</p>
<pre class="prettyprint">
&quot;requirements&quot;: {
&quot;3D&quot;: {
&quot;features&quot;: [&quot;webgl&quot;]
}
}
</pre>
<p>While WebGL is technically a JavaScript API, specifying the <code>webgl</code> feature
also works for OpenGL ES 2.0 because both interfaces use the same driver.</p>
<p>This manifest item is not required, but if you include it, the Chrome Web Store
will prevent a user from installing the application if the browser is running on
a machine that does not support OpenGL ES 2.0 or that is using a known
blacklisted GPU driver that could invite an attack.</p>
<p>If the Web Store determines that the user&#8217;s driver is deficient, the app won&#8217;t
appear on the store&#8217;s tile display. However, it will appear in store search
results or if the user links to it directly, in which case the user could still
download it. But the manifest requirements will be checked when the user reaches
the install page, and if there is a problem, the browser will display the
message &#8220;This application is not supported on this computer. Installation has
been disabled.&#8221;</p>
<p>The manifest-based check applies only to downloads directly from the Chrome Web
Store. It is not performed when an application is loaded via <a class="reference external" href="https://developers.google.com/chrome/web-store/docs/inline_installation">inline
installation</a>.</p>
</section><section id="what-to-do-when-there-are-problems">
<h3 id="what-to-do-when-there-are-problems">What to do when there are problems</h3>
<p>Using the vetting procedure described above, you should be able to detect the
most common problems before your application runs. If there are problems, your
code should describe the issue as clearly as possible. That&#8217;s easy if there is a
missing feature. Failure to create a graphics context is tougher to diagnose. At
the very least, you can suggest that the user try to update the driver. You
might want to linke to the Chrome page that describes <a class="reference external" href="http://support.google.com/chrome/bin/answer.py?hl=en&amp;answer=1202946">how to do updates</a>.</p>
<p>If a user can&#8217;t update the driver, or their problem persists, be sure to gather
information about their graphics environment. Ask for the contents of the Chrome
<code>about:gpu</code> page.</p>
</section><section id="document-unreliable-drivers">
<h3 id="document-unreliable-drivers">Document unreliable drivers</h3>
<p>It can be helpful to include information about known dubious drivers in your
user documentation. This might help identify if a rogue driver is the cause of a
problem. There are many sources of GPU driver blacklists. Two such lists can be
found at the <a class="reference external" href="http://src.chromium.org/viewvc/chrome/trunk/deps/gpu/software_rendering_list/software_rendering_list.json">Chromium project</a>
and <a class="reference external" href="http://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists">Khronos</a>. You
can use these lists to include information in your documentation that warns
users about dangerous drivers.</p>
</section><section id="test-your-defenses">
<h3 id="test-your-defenses">Test your defenses</h3>
<p>You can test your driver validation code by running Chrome with the following
flags (all at once) and watching how your application responds:</p>
<ul class="small-gap">
<li><code>--disable-webgl</code></li>
<li><code>--disable-pepper-3d</code></li>
<li><code>--disable-gl-multisampling</code></li>
<li><code>--disable-accelerated-compositing</code></li>
<li><code>--disable-accelerated-2d-canvas</code></li>
</ul>
</section></section><section id="calling-opengl-es-2-0-commands">
<h2 id="calling-opengl-es-2-0-commands">Calling OpenGL ES 2.0 commands</h2>
<p>There are three ways to write OpenGL ES 2.0 calls in Native Client.</p>
<section id="use-pure-opengl-es-2-0-function-calls">
<h3 id="use-pure-opengl-es-2-0-function-calls">Use &#8220;pure&#8221; OpenGL ES 2.0 function calls</h3>
<p>You can make OpenGL ES 2.0 calls through a Pepper extension library. The SDK
example <code>examples/api/graphics_3d</code> works this way. In the file
<code>graphics_3d.cc</code>, the key initialization steps are as follows:</p>
<ul class="small-gap">
<li><p class="first">Add these includes at the top of the file:</p>
<pre class="prettyprint">
#include &lt;GLES2/gl2.h&gt;
#include &quot;ppapi/lib/gl/gles2/gl2ext_ppapi.h&quot;
</pre>
</li>
<li><p class="first">Define the function <code>InitGL</code>. The exact specification of <code>attrib_list</code>
will be application specific.</p>
<pre class="prettyprint">
bool InitGL(int32_t new_width, int32_t new_height) {
if (!glInitializePPAPI(pp::Module::Get()-&gt;get_browser_interface())) {
fprintf(stderr, &quot;Unable to initialize GL PPAPI!\n&quot;);
return false;
}
const int32_t attrib_list[] = {
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
PP_GRAPHICS3DATTRIB_WIDTH, new_width,
PP_GRAPHICS3DATTRIB_HEIGHT, new_height,
PP_GRAPHICS3DATTRIB_NONE
};
context_ = pp::Graphics3D(this, attrib_list);
if (!BindGraphics(context_)) {
fprintf(stderr, &quot;Unable to bind 3d context!\n&quot;);
context_ = pp::Graphics3D();
glSetCurrentContextPPAPI(0);
return false;
}
glSetCurrentContextPPAPI(context_.pp_resource());
return true;
}
</pre>
</li>
<li>Include logic in <code>Instance::DidChangeView</code> to call <code>InitGL</code> whenever
necessary: upon application launch (when the graphics context is NULL) and
whenever the module&#8217;s View changes size.</li>
</ul>
</section><section id="use-regal">
<h3 id="use-regal">Use Regal</h3>
<p>If you are porting an OpenGL ES 2.0 application, or are comfortable writing in
OpenGL ES 2.0, you should stick with the Pepper APIs or pure OpenGL ES 2.0 calls
described above. If you are porting an application that uses features not in
OpenGL ES 2.0, consider using Regal. Regal is an open source library that
supports many versions of OpenGL. Regal recently added support for Native
Client. Regal forwards most OpenGL calls directly to the underlying graphics
library, but it can also emulate other calls that are not included (when
hardware support exists). See <a class="reference external" href="http://www.altdevblogaday.com/2012/09/04/bringing-regal-opengl-to-native-client/">libregal</a>
for more info.</p>
</section><section id="use-the-pepper-api">
<h3 id="use-the-pepper-api">Use the Pepper API</h3>
<p>Your code can call the Pepper <a class="reference external" href="https://developers.google.com/native-client/pepperc/struct_p_p_b___open_g_l_e_s2">PPB_OpenGLES2</a>
API directly, as with any Pepper interface. When you write in this way, each
invocation of an OpenGL ES 2.0 function must begin with a reference to the
Pepper interface, and the first argument is the graphics context. To invoke the
function <code>glCompileShader</code>, your code might look like:</p>
<pre class="prettyprint">
ppb_g3d_interface-&gt;CompileShader(graphicsContext, shader);
</pre>
<p>This approach specifically targets the Pepper APIs. Each call corresponds to a
OpenGL ES 2.0 function, but the syntax is unique to Native Client, so the source
file is not portable.</p>
</section></section><section id="implementing-a-rendering-loop">
<h2 id="implementing-a-rendering-loop">Implementing a rendering loop</h2>
<p>Graphics applications require a continuous frame render-and-redraw cycle that
runs at a high frequency. To achieve the best frame rate, is important to
understand how the OpenGL ES 2.0 code in a Native Client module interacts with
Chrome.</p>
<section id="the-chrome-and-native-client-processes">
<h3 id="the-chrome-and-native-client-processes">The Chrome and Native Client processes</h3>
<p>Chrome is a multi-process browser. Each Chrome tab is a separate process that is
running an application with its own main thread (we&#8217;ll call it the Chrome main
thread). When an application launches a Native Client module, the module runs in
a new, separate sandboxed process. The module&#8217;s process has its own main thread
(the Native Client thread). The Chrome and Native Client processes communicate
with each other using Pepper API calls on their main threads.</p>
<p>When the Chrome main thread calls the Native Client thread (keyboard and mouse
callbacks, for example), the Chrome main thread will block. This means that
lengthy operations on the Native Client thread can steal cycles from Chrome, and
performing blocking operations on the Native Client thread can bring your app to
a standstill.</p>
<p>Native Client uses callback functions to synchronize the main threads of the two
processes. Only certain Pepper functions use callbacks; <a class="reference external" href="https://developers.google.com/native-client/pepperc/struct_p_p_b___graphics3_d__1__0#a293c6941c0da084267ffba3954793497">SwapBuffers</a>
is one.</p>
</section><section id="swapbuffers-and-its-callback-function">
<h3 id="swapbuffers-and-its-callback-function"><code>SwapBuffers</code> and its callback function</h3>
<p><code>SwapBuffers</code> is non-blocking; it is called from the Native Client thread and
returns immediately. When <code>SwapBuffers</code> is called, it runs asynchronously on
the Chrome main thread. It switches the graphics data buffers, handles any
needed compositing operations, and redraws the screen. When the screen update is
complete, the callback function that was included as one of <code>SwapBuffer</code>&#8216;s
arguments will be called from the Chrome thread and executed on the Native
Client thread.</p>
<p>To create a rendering loop, your Native Client module should include a function
that does the rendering work and then executes <code>SwapBuffers</code>, passing itself
as the <code>SwapBuffer</code> callback. If your rendering code is efficient and runs
quickly, this scheme will achieve the highest frame rate possible. The
documentation for <code>SwapBuffers</code> explains why this is optimal: because the
callback is executed only when the plugin&#8217;s current state is actually on the
screen, this function provides a way to rate-limit animations. By waiting until
the image is on the screen before painting the next frame, you can ensure you&#8217;re
not generating updates faster than the screen can be updated.</p>
<p>The following diagram illustrates the interaction between the Chrome and Native
Client processes. The application-specific rendering code runs in the function
called <code>Draw</code> on the Native Client thread. Blue down-arrows are blocking calls
from the main thread to Native Client, green up-arrows are non-blocking
<code>SwapBuffers</code> calls from Native Client to the main thread. All OpenGL ES 2.0
calls are made from <code>Draw</code> in the Native Client thread.</p>
<img alt="/native-client/images/3d-graphics-render-loop.png" src="/native-client/images/3d-graphics-render-loop.png" />
</section><section id="sdk-example-graphics-3d">
<h3 id="sdk-example-graphics-3d">SDK example <code>graphics_3d</code></h3>
<p>The SDK example <code>graphics_3d</code> uses the function <code>MainLoop</code> (in
<code>hello_world.cc</code>) to create a rendering loop as described above. <code>MainLoop</code>
calls <code>Render</code> to do the rendering work, and then invokes <code>SwapBuffers</code>,
passing itself as the callback.</p>
<pre class="prettyprint">
void MainLoop(void* foo, int bar) {
if (g_LoadCnt == 3) {
InitProgram();
g_LoadCnt++;
}
if (g_LoadCnt &gt; 3) {
Render();
PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0);
ppb_g3d_interface-&gt;SwapBuffers(g_context, cc);
} else {
PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0);
ppb_core_interface-&gt;CallOnMainThread(0, cc, 0);
}
}
</pre>
</section></section><section id="managing-the-opengl-es-2-0-pipeline">
<h2 id="managing-the-opengl-es-2-0-pipeline">Managing the OpenGL ES 2.0 pipeline</h2>
<p>OpenGL ES 2.0 commands do not run in the Chrome or Native Client processes. They
are passed into a FIFO queue in shared memory which is best understood as a <a class="reference external" href="http://www.chromium.org/developers/design-documents/gpu-command-buffer">GPU
command buffer</a>. The
command buffer is shared by a dedicated GPU process. By using a separate GPU
process, Chrome implements another layer of runtime security, vetting all OpenGL
ES 2.0 commands and their arguments before they are sent on to the
GPU. Buffering commands through the FIFO also speeds up your code, since each
OpenGL ES 2.0 call in your Native Client thread returns immediately, while the
processing may be delayed as the GPU works down the commands queued up in the
FIFO.</p>
<p>Before the screen is updated, all the intervening OpenGL ES 2.0 commands must be
processed by the GPU. Programmers often try to ensure this by using the
<code>glFlush</code> and <code>glFinish</code> commands in their rendering code. In the case of
Native Client this is usually unnecessary. The <code>SwapBuffers</code> command does an
implicit flush, and the Chrome team is continually tweaking the GPU code to
consume the OpenGL ES 2.0 FIFO as fast as possible.</p>
<p>Sometimes a 3D application can write to the FIFO in a way that&#8217;s difficult to
handle. The command pipeline may fill up and your code will have to wait for the
GPU to flush the FIFO. If this is the case, you may be able to add <code>glFlush</code>
calls to speed up the flow of the OpenGL ES 2.0 command FIFO. Before you start
to add your own flushes, first try to determine if pipeline saturation is really
the problem by monitoring the rendering time per frame and looking for irregular
spikes that do not consistently fall on the same OpenGL ES 2.0 call. If you&#8217;re
convinced the pipeline needs to be accelerated, insert <code>glFlush</code> calls in your
code before starting blocks of processing that do not generate OpenGL ES 2.0
commands. For example, issue a flush before you begin any multithreaded particle
work, so that the command buffer will be clear when you start doing OpenGL ES
2.0 calls again. Determining where and how often to call <code>glFlush</code> can be
tricky, you will need to experiment to find the sweet spot.</p>
</section><section id="rendering-and-inactive-tabs">
<h2 id="rendering-and-inactive-tabs">Rendering and inactive tabs</h2>
<p>Users will often switch between tabs in a multi-tab browser. A well-behaved
application that&#8217;s performing 3D rendering should pause any real-time processing
and yield cycles to other processes when its tab becomes inactive.</p>
<p>In Chrome, an inactive tab will continue to execute timed functions (such as
<code>setInterval</code> and <code>setTimeout</code>) but the timer interval will be automatically
overridden and limited to not less than one second while the tab is inactive. In
addition, any callback associated with a <code>SwapBuffers</code> call will not be sent
until the tab is active again. You may receive asynchronous callbacks from
functions other than <code>SwapBuffers</code> while a tab is inactive. Depending on the
design of your application, you might choose to handle them as they arrive, or
to queue them in a buffer and process them when the tab becomes active.</p>
<p>The time that passes while a tab is inactive can be considerable. If your main
thread pulse is based on the <code>SwapBuffers</code> callback, your app won&#8217;t update
while a tab is inactive. A Native Client module should be able to detect and
respond to the state of the tab in which it&#8217;s running. For example, when a tab
becomes inactive, you can set an atomic flag in the Native Client thread that
will skip the 3D rendering and <code>SwapBuffers</code> calls and continue to call the
main thread every 30 msec or so. This provides time to update features that
should still run in the background, like audio. It may also be helpful to call
<code>sched_yield</code> or <code>usleep</code> on any worker threads to release resources and
cede cycles to the OS.</p>
<section id="handling-tab-activation-from-the-main-thread">
<h3 id="handling-tab-activation-from-the-main-thread">Handling tab activation from the main thread</h3>
<p>You can detect and respond to the activation or deactivation of a tab with
JavaScript on your hosting page. Add an EventListener for <code>visibilitychange</code>
that sends a message to the Native Client module, as in this example:</p>
<pre class="prettyprint">
document.addEventListener('visibilitychange', function(){
if (document.hidden) {
// PostMessage to your Native Client module
document.nacl_module.postMessage('INACTIVE');
} else {
// PostMessage to your Native Client module
document.nacl_module.postMessage('ACTIVE');
}
}, false);
</pre>
</section><section id="handling-tab-activation-from-the-native-client-thread">
<h3 id="handling-tab-activation-from-the-native-client-thread">Handling tab activation from the Native Client thread</h3>
<p>You can also detect and respond to the activation or deactivation of a tab
directly from your Native Client module by including code in the function
<code>pp::Instance::DidChangeView</code>, which is called whenever a change in the
module&#8217;s view occurs. The code can call <code>ppb::View::IsPageVisible</code> to
determine if the page is visible or not. The most common cause of invisible
pages is that the page is in a background tab.</p>
</section></section><section id="tips-and-best-practices">
<h2 id="tips-and-best-practices">Tips and best practices</h2>
<p>Here are some suggestions for writing safe code and getting the maximum
performance with the Pepper 3D API.</p>
<section id="do-s">
<h3 id="do-s">Do&#8217;s</h3>
<ul class="small-gap">
<li><p class="first"><strong>Make sure to enable attrib 0.</strong> OpenGL requires that you enable attrib 0,
but OpenGL ES 2.0 does not. For example, you can define a vertex shader with 2
attributes, numbered like this:</p>
<pre class="prettyprint">
glBindAttribLocation(program, &quot;positions&quot;, 1);
glBindAttribLocation(program, &quot;normals&quot;, 2);
</pre>
<p>In this case the shader is not using attrib 0 and Chrome may have to perform
some additional work if it is emulating OpenGL ES 2.0 on top of OpenGL. It&#8217;s
always more efficient to enable attrib 0, even if you do not use it.</p>
</li>
<li><strong>Check how shaders compile.</strong> Shaders can compile differently on different
systems, which can result in <code>glGetAttrib*</code> functions returning different
results. Be sure that the vertex attribute indices match the corresponding
name each time you recompile a shader.</li>
<li><strong>Update indices sparingly.</strong> For security reasons, all indices must be
validated. If you change indices, Native Client will validate them
again. Structure your code so indices are not updated often.</li>
<li><strong>Use a smaller plugin and let CSS scale it.</strong> If you&#8217;re running into fillrate
issues, it may be beneficial to perform scaling via CSS. The size your plugin
renders is determined by the width and height attributes of the <code>&lt;embed&gt;</code>
element for the module. The actual size displayed on the web page is
controlled by the CSS styles applied to the element.</li>
<li><strong>Avoid matrix-to-matrix conversions.</strong> With some versions of Mac OS, there is
a driver problem when compiling shaders. If you get compiler errors for matrix
transforms, avoid matrix-to-matrix conversions. For instance, upres a vec3 to
a vec4 before transforming it by a mat4, rather than converting the mat4 to a
mat3.</li>
</ul>
</section><section id="don-ts">
<h3 id="don-ts">Don&#8217;ts</h3>
<ul class="small-gap">
<li><strong>Don&#8217;t use client side buffers.</strong> OpenGL ES 2.0 can use client side data with
<code>glVertexAttribPointer</code> and <code>glDrawElements</code>, but this is really slow. Try
to avoid client side buffers. Use Vertex Buffer Objects (VBOs) instead.</li>
<li><strong>Don&#8217;t mix vertex data and index data.</strong> By default, Pepper 3D binds buffers
to a single point. You could create a buffer and bind it to both
<code>GL_ARRAY_BUFFER</code> and <code>GL_ELEMENT_ARRAY_BUFFER</code>, but that would be
expensive overhead and it is not recommended.</li>
<li><strong>Don&#8217;t call ``glGet*`` or ``glCheck*`` during rendering.</strong> This is normal
advice for OpenGL programs, but is particularly important for 3D on
Chrome. Calls to any OpenGL ES 2.0 function whose name begins with these
strings blocks the Native Client thread. This includes <code>glGetError</code>; avoid
calling it in release builds.</li>
<li><strong>Don&#8217;t use fixed point (``GL_FIXED``) vertex attributes.</strong> Fixed point
attributes are not supported in OpenGL ES 2.0, so emulating them in OpenGL ES
2.0 is slow. By default, <code>GL_FIXED</code> support is turned off in the Pepper 3D
API.</li>
<li><strong>Don&#8217;t read data from the GPU.</strong> Don&#8217;t call <code>glReadPixels</code>, as it is slow.</li>
<li><strong>Don&#8217;t update a small portion of a large buffer.</strong> In the current OpenGL ES
2.0 implementation when you update a portion of a buffer (with
<code>glSubBufferData</code> for example) the entire buffer must be reprocessed. To
avoid this problem, keep static and dynamic data in different buffers.</li>
<li><strong>Don&#8217;t call ``glDisable(GL_TEXTURE_2D)``.</strong> This is an OpenGL ES 2.0
error. Each time it is called, an error messages will appear in Chrome&#8217;s
<code>about:gpu</code> tab.</li>
</ul>
</section></section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,216 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="application-structure">
<span id="devcycle-application-structure"></span><h1 id="application-structure"><span id="devcycle-application-structure"></span>Application Structure</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#application-components" id="id1">Application components</a></li>
<li><a class="reference internal" href="#html-file-and-the-embed-element" id="id2">HTML file and the &lt;embed&gt; element</a></li>
<li><a class="reference internal" href="#manifest-files" id="id3">Manifest Files</a></li>
<li><a class="reference internal" href="#modules-and-instances" id="id4">Modules and instances</a></li>
<li><a class="reference internal" href="#native-client-modules-a-closer-look" id="id5">Native Client modules: A closer look</a></li>
</ul>
</div>
<p>This chapter of the Developer&#8217;s Guide describes the general structure of a
Native Client application. The chapter assumes you are familiar with the
material presented in the <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p>
<aside class="note">
The &#8220;Hello, World&#8221; example is used here to illustrate basic
Native Client programming techniques. You can find this code in the
<em>/getting_started/part1</em> directory in the Native Client SDK download.
</aside>
<section id="application-components">
<h2 id="application-components">Application components</h2>
<p>A Native Client application typically contains the following components:</p>
<ul class="small-gap">
<li>an HTML file;</li>
<li>JavaScript code, which can be included in the HTML file or contained in one or
more separate .js files;</li>
<li>CSS styles, which can be included in the HTML file or contained in one or more
separate .css files;</li>
<li>a Native Client manifest file (with a .nmf extension) that specifies how to
load a Native Client module for different processors; and</li>
<li>a Native Client module, written in C or C++, and compiled into a portable
executable file (with a .pexe extension) or (if using the Chrome Web Store),
architecture-specific executable files (with .nexe extensions).</li>
</ul>
<p>Applications that are published in the <a class="reference external" href="https://chrome.google.com/webstore/search?q=%22Native+Client%22+OR+NativeClient+OR+NaCl">Chrome Web Store</a>
also include a Chrome
Web Store manifest file <code>(manifest.json)</code> and one or more icon files.</p>
</section><section id="html-file-and-the-embed-element">
<span id="html-file"></span><h2 id="html-file-and-the-embed-element"><span id="html-file"></span>HTML file and the &lt;embed&gt; element</h2>
<p>The <code>&lt;embed&gt;</code> element in an HTML file triggers the loading of a Native Client
module and specifies the rectangle on the web page that is managed by the
module. Here is the &lt;embed&gt; element from the &#8220;Hello, World&#8221; application:</p>
<pre class="prettyprint">
&lt;embed id=&quot;hello_tutorial&quot;
width=0 height=0
src=&quot;hello_tutorial.nmf&quot;
type=&quot;application/x-pnacl&quot; /&gt;
</pre>
<p>In the <code>&lt;embed&gt;</code> element:</p>
<dl class="docutils">
<dt>name</dt>
<dd>is the DOM name attribute for the Native Client module
(&#8220;nacl_module&#8221; is often used as a convention)</dd>
<dt>id</dt>
<dd>specifies the DOM ID for the Native Client module</dd>
<dt>width, height</dt>
<dd>specify the size in pixels of the rectangle on the web page that is
managed by the Native Client module (if the module does not have a
visible area, these values can be 0)</dd>
<dt>src</dt>
<dd>refers to the Native Client manifest file that is used to determine
which version of a module to load based on the architecture of the
user&#8217;s computer (see the following section for more information)</dd>
<dt>type</dt>
<dd>specifies the MIME type of the embedded content; for Portable Native Client
modules the type must be &#8220;application/x-pnacl&#8221;. For architecture-specific
Native Client modules the type must be &#8220;application/x-nacl&#8221;</dd>
</dl>
</section><section id="manifest-files">
<span id="manifest-file"></span><h2 id="manifest-files"><span id="manifest-file"></span>Manifest Files</h2>
<p>Native Client applications have two types of manifest files: a Chrome Web Store
manifest file and a Native Client manifest file.</p>
<p>A <strong>Chrome Web Store manifest file</strong> is a file with information about a web
application that is published in the Chrome Web Store. This file, named
<code>manifest.json</code>, is required for applications that are published in the Chrome
Web Store. For more information about this file see <a class="reference internal" href="/native-client/devguide/distributing.html"><em>Distributing Your
Application</em></a>. and the <a class="reference external" href="http://code.google.com/chrome/extensions/manifest.html">Chrome Web Store manifest file format</a>.</p>
<p>A <strong>Native Client manifest file</strong> is a file that specifies which Native Client
module (executable) to load. For PNaCl it specifies a single portable
executable; otherwise it specifies one for each of the supported end-user
computer architectures (for example x86-32, x86-64, or ARM). This file is
required for all Native Client applications. The extension for this file is
.nmf.</p>
<p>Manifest files for applications that use PNaCl are simple. Here is the manifest
for the hello world example:</p>
<pre class="prettyprint">
{
&quot;program&quot;: {
&quot;portable&quot;: {
&quot;pnacl-translate&quot;: {
&quot;url&quot;: &quot;hello_tutorial.pexe&quot;
}
}
}
}
</pre>
<p>For Chrome Web Store applications that do not use PNaCl, a typical manifest file
contains a <a class="reference external" href="http://www.json.org/">JSON</a> dictionary with a single top-level
key/value pair: the &#8220;program&#8221; key and a value consisting of a nested
dictionary. The nested dictionary contains keys corresponding to the names of
the supported computer architectures, and values referencing the file to load
for a given architecture—specifically, the URL of the .nexe file, given by the
<code>&quot;url&quot;</code> key. URLs are specified relative to the location of the manifest file.
Here is an example:</p>
<pre class="prettyprint">
{
&quot;program&quot;: {
&quot;x86-32&quot;: {
&quot;url&quot;: &quot;hello_tutorial_x86_32.nexe&quot;
},
&quot;x86-64&quot;: {
&quot;url&quot;: &quot;hello_tutorial_x86_64.nexe&quot;
},
&quot;arm&quot;: {
&quot;url&quot;: &quot;hello_tutorial_arm.nexe&quot;
}
}
}
</pre>
<p>For applications that use the <a class="reference internal" href="/native-client/devguide/devcycle/dynamic-loading.html#c-libraries"><em>glibc</em></a>
library, the manifest file must also contain a &#8220;files&#8221; key that specifies the
shared libraries that the applications use. This is discussed in detail in
<a class="reference internal" href="/native-client/devguide/devcycle/dynamic-loading.html"><em>Dynamic Linking and Loading with glibc</em></a>. To
see some example manifest files, build some of the example applications in the
SDK (run <code>make</code> in the example subdirectories) and look at the generated
manifest files.</p>
<p>In most cases, you can simply use the Python script provided with the SDK,
<code>create_nmf.py</code>, to create a manifest file for your application as part of the
compilation step (see the Makefile in any of the SDK examples for an
illustration of how to do so). The manifest file format is also
<a class="reference internal" href="/native-client/reference/nacl-manifest-format.html"><em>documented</em></a>.</p>
</section><section id="modules-and-instances">
<h2 id="modules-and-instances">Modules and instances</h2>
<p>A Native Client <strong>module</strong> is C or C++ code compiled into a PNaCl .pexe file or
a NaCl .nexe file.</p>
<p>An <strong>instance</strong> is a rectangle on a web page that is managed by a module. An
instance may have a dimension of width=0 and height=0, meaning that the instance
does not have any visible component on the web page. An instance is created by
including an <code>&lt;embed&gt;</code> element in a web page. The <code>&lt;embed&gt;</code> element
references a Native Client manifest file that loads the appropriate version of
the module (either portable, or specific to the end-user&#8217;s architecture). A
module may be included in a web page multiple times by using multiple
<code>&lt;embed&gt;</code> elements that refer to the module; in this case the Native Client
runtime system loads the module once and creates multiple instances that are
managed by the module.</p>
</section><section id="native-client-modules-a-closer-look">
<h2 id="native-client-modules-a-closer-look">Native Client modules: A closer look</h2>
<p>A Native Client module must include three components:</p>
<ul class="small-gap">
<li>a factory function called <code>CreateModule()</code></li>
<li>a Module class (derived from the <code>pp::Module</code> class)</li>
<li>an Instance class (derived from the <code>pp:Instance</code> class)</li>
</ul>
<p>In the &#8220;Hello tutorial&#8221; example (in the <code>getting_started/part1</code> directory of
the NaCl SDK), these three components are specified in the file
<code>hello_tutorial.cc</code>. Here is the factory function:</p>
<pre class="prettyprint">
Module* CreateModule() {
return new HelloTutorialModule();
}
</pre>
<p>Native Client modules do not have a <code>main()</code> function. The <code>CreateModule()</code>
factory function is the main binding point between a module and the browser, and
serves as the entry point into the module. The browser calls <code>CreateModule()</code>
when a module is first loaded; this function returns a Module object derived
from the <code>pp::Module</code> class. The browser keeps a singleton of the Module
object.</p>
<p>Below is the Module class from the &#8220;Hello tutorial&#8221; example:</p>
<pre class="prettyprint">
class HelloTutorialModule : public pp::Module {
public:
HelloTutorialModule() : pp::Module() {}
virtual ~HelloTutorialModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new HelloTutorialInstance(instance);
}
};
</pre>
<p>The Module class must include a <code>CreateInstance()</code> method. The browser calls
the <code>CreateInstance()</code> method every time it encounters an <code>&lt;embed&gt;</code> element
on a web page that references the same module. The <code>CreateInstance()</code> function
creates and returns an Instance object derived from the <code>pp::Instance</code> class.</p>
<p>Below is the Instance class from the &#8220;Hello tutorial&#8221; example:</p>
<pre class="prettyprint">
class HelloTutorialInstance : public pp::Instance {
public:
explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance) {}
virtual ~HelloTutorialInstance() {}
virtual void HandleMessage(const pp::Var&amp; var_message) {}
};
</pre>
<p>As in the example above, the Instance class for your module will likely include
an implementation of the <code>HandleMessage()</code> function. The browser calls an
instance&#8217;s <code>HandleMessage()</code> function every time the JavaScript code in an
application calls <code>postMessage()</code> to send a message to the instance. See the
<a class="reference internal" href="/native-client/devguide/coding/message-system.html"><em>Native Client messaging system</em></a> for more information about
how to send messages between JavaScript code and Native Client modules.</p>
<p>The NaCl code is only invoked to handle various browser-issued
events and callbacks. There is no need to shut down the NaCl instance by
calling the <code>exit()</code> function. NaCl modules will be shut down when the user
leaves the web page, or the NaCl module&#8217;s <code>&lt;embed&gt;</code> is otherwise destroyed.
If the NaCl module does call the <code>exit()</code> function, the instance will
issue a <code>crash</code> event
<a class="reference internal" href="/native-client/devguide/coding/progress-events.html"><em>which can be handled in Javascript</em></a>.</p>
<p>While the <code>CreateModule()</code> factory function, the <code>Module</code> class, and the
<code>Instance</code> class are required for a Native Client application, the code
samples shown above don&#8217;t actually do anything. Subsequent chapters in the
Developer&#8217;s Guide build on these code samples and add more interesting
functionality.</p>
</section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,352 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="audio">
<span id="devguide-coding-audio"></span><h1 id="audio"><span id="devguide-coding-audio"></span>Audio</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#reference-information" id="id1">Reference information</a></li>
<li><a class="reference internal" href="#about-the-pepper-audio-api" id="id2">About the Pepper audio API</a></li>
<li><a class="reference internal" href="#digital-audio-concepts" id="id3">Digital audio concepts</a></li>
<li><a class="reference internal" href="#setting-up-the-module" id="id4">Setting up the module</a></li>
<li><p class="first"><a class="reference internal" href="#creating-an-audio-configuration-resource" id="id5">Creating an audio configuration resource</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#resources" id="id6">Resources</a></li>
<li><a class="reference internal" href="#sample-frame-count" id="id7">Sample frame count</a></li>
<li><a class="reference internal" href="#supported-audio-configurations" id="id8">Supported audio configurations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#creating-an-audio-resource" id="id9">Creating an audio resource</a></li>
<li><p class="first"><a class="reference internal" href="#implementing-a-callback-function" id="id10">Implementing a callback function</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#application-threads-and-real-time-requirements" id="id11">Application threads and real-time requirements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#starting-and-stopping-playback" id="id12">Starting and stopping playback</a></li>
</ul>
</div>
<p>This chapter describes how to use the Pepper audio API to play an audio
stream. The Pepper audio API provides a low-level means of playing a stream of
audio samples generated by a Native Client module. The API generally works as
follows: A Native Client module creates an audio resource that represents an
audio stream, and tells the browser to start or stop playing the audio
resource. The browser calls a function in the Native Client module to fill a
buffer with audio samples every time it needs data to play from the audio
stream.</p>
<p>The code examples in this chapter describe a simple Native Client module that
generates audio samples using a sine wave with a frequency of 440 Hz. The module
starts playing the audio samples as soon as it is loaded into the browser. For a
slightly more sophisticated example, see the <code>audio</code> example (source code in
the SDK directory <code>examples/api/audio</code>), which lets users specify a frequency
for the sine wave and click buttons to start and stop audio playback.</p>
<section id="reference-information">
<h2 id="reference-information">Reference information</h2>
<p>For reference information related to the Pepper audio API, see the following
documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_audio_config">pp::AudioConfig class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_audio">pp::Audio class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/audio__config_8h">audio_config.h</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/audio_8h">audio.h</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/pepperc/group___enums.html#gaee750c350655f2fb0fe04c04029e0ff8">PP_AudioSampleRate</a></li>
</ul>
</section><section id="about-the-pepper-audio-api">
<h2 id="about-the-pepper-audio-api">About the Pepper audio API</h2>
<p>The Pepper audio API lets Native Client modules play audio streams in a
browser. To play an audio stream, a module generates audio samples and writes
them into a buffer. The browser reads the audio samples from the buffer and
plays them using an audio device on the client computer.</p>
<img alt="/native-client/images/pepper-audio-buffer.png" src="/native-client/images/pepper-audio-buffer.png" />
<p>This mechanism is simple but low-level. If you want to play plain sound files in
a web application, you may want to consider higher-level alternatives such as
using the HTML <code>&lt;audio&gt;</code> tag, JavaScript, or the new <a class="reference external" href="http://chromium.googlecode.com/svn/trunk/samples/audio/index.html">Web Audio API</a>.</p>
<p>The Pepper audio API is a good option for playing audio data if you want to do
audio processing in your web application. You might use the audio API, for
example, if you want to apply audio effects to sounds, synthesize your own
sounds, or do any other type of CPU-intensive processing of audio
samples. Another likely use case is gaming applications: you might use a gaming
library to process audio data, and then simply use the audio API to output the
processed data.</p>
<p>The Pepper audio API is straightforward to use:</p>
<ol class="arabic simple">
<li>Your module creates an audio configuration resource and an audio resource.</li>
<li>Your module implements a callback function that fills an audio buffer with
data.</li>
<li>Your module invokes the StartPlayback and StopPlayback methods of the audio
resource (e.g., when certain events occur).</li>
<li>The browser invokes your callback function whenever it needs audio data to
play. Your callback function can generate the audio data in a number of
ways&#8212;e.g., it can generate new data, or it can copy pre-mixed data into the
audio buffer.</li>
</ol>
<p>This basic interaction is illustrated below, and described in detail in the
sections that follow.</p>
<img alt="/native-client/images/pepper-audio-api.png" src="/native-client/images/pepper-audio-api.png" />
</section><section id="digital-audio-concepts">
<h2 id="digital-audio-concepts">Digital audio concepts</h2>
<p>Before you use the Pepper audio API, it&#8217;s helpful to understand a few concepts
that are fundamental to how digital audio is recorded and played back:</p>
<dl class="docutils">
<dt>sample rate</dt>
<dd>the number of times an input sound source is sampled per second;
correspondingly, the number of samples that are played back per second</dd>
<dt>bit depth</dt>
<dd>the number of bits used to represent a sample</dd>
<dt>channels</dt>
<dd>the number of input sources recorded in each sampling interval;
correspondingly, the number of outputs that are played back simultaneously
(typically using different speakers)</dd>
</dl>
<p>The higher the sample rate and bit depth used to record a sound wave, the more
accurately the sound wave can be reproduced, since it will have been sampled
more frequently and stored using a higher level of quantization. Common sampling
rates include 44,100 Hz (44,100 samples/second, the sample rate used on CDs),
and 48,000 Hz (the sample rate used on DVDs and Digital Audio Tapes). A common
bit depth is 16 bits per sample, and a common number of channels is 2 (left and
right channels for stereo sound).</p>
<p id="pepper-audio-configurations">The Pepper audio API currently lets Native Client modules play audio streams
with the following configurations:</p>
<ul class="small-gap">
<li><strong>sample rate</strong>: 44,100 Hz or 48,000 Hz</li>
<li><strong>bit depth</strong>: 16</li>
<li><strong>channels</strong>: 2 (stereo)</li>
</ul>
</section><section id="setting-up-the-module">
<h2 id="setting-up-the-module">Setting up the module</h2>
<p>The code examples below describe a simple Native Client module that generates
audio samples using a sine wave with a frequency of 440 Hz. The module starts
playing the audio samples as soon as it is loaded into the browser.</p>
<p>The Native Client module is set up by implementing subclasses of the
<code>pp::Module</code> and <code>pp::Instance</code> classes, as normal.</p>
<pre class="prettyprint">
class SineSynthInstance : public pp::Instance {
public:
explicit SineSynthInstance(PP_Instance instance);
virtual ~SineSynthInstance() {}
// Called by the browser once the NaCl module is loaded and ready to
// initialize. Creates a Pepper audio context and initializes it. Returns
// true on success. Returning false causes the NaCl module to be deleted
// and no other functions to be called.
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
private:
// Function called by the browser when it needs more audio samples.
static void SineWaveCallback(void* samples,
uint32_t buffer_size,
void* data);
// Audio resource.
pp::Audio audio_;
...
};
class SineSynthModule : public pp::Module {
public:
SineSynthModule() : pp::Module() {}
~SineSynthModule() {}
// Create and return a SineSynthInstance object.
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new SineSynthInstance(instance);
}
};
</pre>
</section><section id="creating-an-audio-configuration-resource">
<h2 id="creating-an-audio-configuration-resource">Creating an audio configuration resource</h2>
<section id="resources">
<h3 id="resources">Resources</h3>
<p>Before the module can play an audio stream, it must create two resources: an
audio configuration resource and an audio resource. Resources are handles to
objects that the browser provides to module instances. An audio resource is an
object that represents the state of an audio stream, including whether the
stream is paused or being played back, and which callback function to invoke
when the samples in the stream&#8217;s buffer run out. An audio configuration resource
is an object that stores configuration data for an audio resource, including the
sampling frequency of the audio samples, and the number of samples that the
callback function must provide when the browser invokes it.</p>
</section><section id="sample-frame-count">
<h3 id="sample-frame-count">Sample frame count</h3>
<p>Prior to creating an audio configuration resource, the module should call
<code>RecommendSampleFrameCount</code> to obtain a <em>sample frame count</em> from the
browser. The sample frame count is the number of samples that the callback
function must provide per channel each time the browser invokes the callback
function. For example, if the sample frame count is 4096 for a stereo audio
stream, the callback function must provide a 8192 samples (4096 for the left
channel and 4096 for the right channel).</p>
<p>The module can request a specific sample frame count, but the browser may return
a different sample frame count depending on the capabilities of the client
device. At present, <code>RecommendSampleFrameCount</code> simply bound-checks the
requested sample frame count (see <code>include/ppapi/c/ppb_audio_config.h</code> for the
minimum and maximum sample frame counts, currently 64 and 32768). In the future,
<code>RecommendSampleFrameCount</code> may perform a more sophisticated calculation,
particularly if there is an intrinsic buffer size for the client device.</p>
<p>Selecting a sample frame count for an audio stream involves a tradeoff between
latency and CPU usage. If you want your module to have short audio latency so
that it can rapidly change what&#8217;s playing in the audio stream, you should
request a small sample frame count. That could be useful in gaming applications,
for example, where sounds have to change frequently in response to game
action. However, a small sample frame count results in higher CPU usage, since
the browser must invoke the callback function frequently to refill the audio
buffer. Conversely, a large sample frame count results in higher latency but
lower CPU usage. You should request a large sample frame count if your module
will play long, uninterrupted audio segments.</p>
</section><section id="supported-audio-configurations">
<h3 id="supported-audio-configurations">Supported audio configurations</h3>
<p>After the module obtains a sample frame count, it can create an audio
configuration resource. Currently the Pepper audio API supports audio streams
with the configuration settings shown <a class="reference internal" href="#pepper-audio-configurations"><em>above</em></a>.
C++ modules can create a configuration resource by instantiating a
<code>pp::AudioConfig</code> object. Check <code>audio_config.h</code> for the latest
configurations that are supported.</p>
<pre class="prettyprint">
bool SineSynthInstance::Init(uint32_t argc,
const char* argn[],
const char* argv[]) {
// Ask the browser/device for an appropriate sample frame count size.
sample_frame_count_ =
pp::AudioConfig::RecommendSampleFrameCount(PP_AUDIOSAMPLERATE_44100,
kSampleFrameCount);
// Create an audio configuration resource.
pp::AudioConfig audio_config = pp::AudioConfig(this,
PP_AUDIOSAMPLERATE_44100,
sample_frame_count_);
// Create an audio resource.
audio_ = pp::Audio(this,
audio_config,
SineWaveCallback,
this);
// Start playback when the module instance is initialized.
return audio_.StartPlayback();
}
</pre>
</section></section><section id="creating-an-audio-resource">
<h2 id="creating-an-audio-resource">Creating an audio resource</h2>
<p>Once the module has created an audio configuration resource, it can create an
audio resource. To do so, it instantiates a <code>pp::Audio</code> object, passing in a
pointer to the module instance, the audio configuration resource, a callback
function, and a pointer to user data (data that is used in the callback
function). See the example above.</p>
</section><section id="implementing-a-callback-function">
<h2 id="implementing-a-callback-function">Implementing a callback function</h2>
<p>The browser calls the callback function associated with an audio resource every
time it needs more samples to play. The callback function can generate new
samples (e.g., by applying sound effects), or copy pre-mixed samples into the
audio buffer. The example below generates new samples by computing values of a
sine wave.</p>
<p>The last parameter passed to the callback function is generic user data that the
function can use in processing samples. In the example below, the user data is a
pointer to the module instance, which includes member variables
<code>sample_frame_count_</code> (the sample frame count obtained from the browser) and
<code>theta_</code> (the last angle that was used to compute a sine value in the previous
callback; this lets the function generate a smooth sine wave by starting at that
angle plus a small delta).</p>
<pre class="prettyprint">
class SineSynthInstance : public pp::Instance {
public:
...
private:
static void SineWaveCallback(void* samples,
uint32_t buffer_size,
void* data) {
// The user data in this example is a pointer to the module instance.
SineSynthInstance* sine_synth_instance =
reinterpret_cast&lt;SineSynthInstance*&gt;(data);
// Delta by which to increase theta_ for each sample.
const double delta = kTwoPi * kFrequency / PP_AUDIOSAMPLERATE_44100;
// Amount by which to scale up the computed sine value.
const int16_t max_int16 = std::numeric_limits&lt;int16_t&gt;::max();
int16_t* buff = reinterpret_cast&lt;int16_t*&gt;(samples);
// Make sure we can't write outside the buffer.
assert(buffer_size &gt;= (sizeof(*buff) * kChannels *
sine_synth_instance-&gt;sample_frame_count_));
for (size_t sample_i = 0;
sample_i &lt; sine_synth_instance-&gt;sample_frame_count_;
++sample_i, sine_synth_instance-&gt;theta_ += delta) {
// Keep theta_ from going beyond 2*Pi.
if (sine_synth_instance-&gt;theta_ &gt; kTwoPi) {
sine_synth_instance-&gt;theta_ -= kTwoPi;
}
// Compute the sine value for the current theta_, scale it up,
// and write it into the buffer once for each channel.
double sin_value(std::sin(sine_synth_instance-&gt;theta_));
int16_t scaled_value = static_cast&lt;int16_t&gt;(sin_value * max_int16);
for (size_t channel = 0; channel &lt; kChannels; ++channel) {
*buff++ = scaled_value;
}
}
}
...
};
</pre>
<section id="application-threads-and-real-time-requirements">
<h3 id="application-threads-and-real-time-requirements">Application threads and real-time requirements</h3>
<p>The callback function runs in a background application thread. This allows audio
processing to continue even when the application is busy doing something
else. If the main application thread and the callback thread access the same
data, you may be tempted to use a lock to control access to that data. You
should avoid the use of locks in the callback thread, however, as attempting to
acquire a lock may cause the thread to get swapped out, resulting in audio
dropouts.</p>
<p>In general, you must program the callback thread carefully, as the Pepper audio
API is a very low level API that needs to meet hard real-time requirements. If
the callback thread spends too much time processing, it can easily miss the
real-time deadline, resulting in audio dropouts. One way the callback thread can
miss the deadline is by taking too much time doing computation. Another way the
callback thread can miss the deadline is by executing a function call that swaps
out the callback thread. Unfortunately, such function calls include just about
all C Run-Time (CRT) library calls and Pepper API calls. The callback thread
should therefore avoid calls to malloc, gettimeofday, mutex, condvars, critical
sections, and so forth; any such calls could attempt to take a lock and swap out
the callback thread, which would be disastrous for audio playback. Similarly,
the callback thread should avoid Pepper API calls. Audio dropouts due to thread
swapping can be very rare and very hard to track down and debug&#8212;it&#8217;s best to
avoid making system/Pepper calls in the first place. In short, the audio
(callback) thread should use &#8220;lock-free&#8221; techniques and avoid making CRT library
calls.</p>
<p>One other issue to be aware of is that the <code>StartPlayback</code> function (discussed
below) is an asynchronous RPC; i.e., it does not block. That means that the
callback function may not be called immediately after the call to
<code>StartPlayback</code>. If it&#8217;s important to synchronize the callback thread with
another thread so that the audio stream starts playing simultaneously with
another action in your application, you must handle such synchronization
manually.</p>
</section></section><section id="starting-and-stopping-playback">
<h2 id="starting-and-stopping-playback">Starting and stopping playback</h2>
<p>To start and stop audio playback, the module simply reacts to JavaScript
messages.</p>
<pre class="prettyprint">
const char* const kPlaySoundId = &quot;playSound&quot;;
const char* const kStopSoundId = &quot;stopSound&quot;;
void SineSynthInstance::HandleMessage(const pp::Var&amp; var_message) {
if (!var_message.is_string()) {
return;
}
std::string message = var_message.AsString();
if (message == kPlaySoundId) {
audio_.StartPlayback();
} else if (message == kStopSoundId) {
audio_.StopPlayback();
} else if (...) {
...
}
}
</pre>
</section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,498 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="file-i-o">
<span id="devguide-coding-fileio"></span><h1 id="file-i-o"><span id="devguide-coding-fileio"></span>File I/O</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#introduction" id="id2">Introduction</a></li>
<li><a class="reference internal" href="#reference-information" id="id3">Reference information</a></li>
<li><p class="first"><a class="reference internal" href="#local-file-i-o" id="id4">Local file I/O</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#enabling-local-file-i-o" id="id5">Enabling local file I/O</a></li>
<li><a class="reference internal" href="#testing-local-file-i-o" id="id6">Testing local file I/O</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#the-file-io-example" id="id7">The <code>file_io</code> example</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#file-i-o-overview" id="id8">File I/O overview</a></li>
<li><a class="reference internal" href="#creating-and-writing-a-file" id="id9">Creating and writing a file</a></li>
<li><a class="reference internal" href="#opening-and-reading-a-file" id="id10">Opening and reading a file</a></li>
<li><a class="reference internal" href="#deleting-a-file" id="id11">Deleting a file</a></li>
<li><a class="reference internal" href="#making-a-directory" id="id12">Making a directory</a></li>
<li><a class="reference internal" href="#listing-the-contents-of-a-directory" id="id13">Listing the contents of a directory</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#file-io-deep-dive" id="id14"><code>file_io</code> deep dive</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#opening-a-file-system-and-preparing-for-file-i-o" id="id15">Opening a file system and preparing for file I/O</a></li>
<li><a class="reference internal" href="#handling-messages-from-javascript" id="id16">Handling messages from JavaScript</a></li>
<li><a class="reference internal" href="#saving-a-file" id="id17">Saving a file</a></li>
<li><a class="reference internal" href="#loading-a-file" id="id18">Loading a file</a></li>
<li><a class="reference internal" href="#id1" id="id19">Deleting a file</a></li>
<li><a class="reference internal" href="#listing-files-in-a-directory" id="id20">Listing files in a directory</a></li>
<li><a class="reference internal" href="#making-a-new-directory" id="id21">Making a new directory</a></li>
</ul>
</li>
</ul>
</div>
<section id="introduction">
<h2 id="introduction">Introduction</h2>
<p>This chapter describes how to use the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_file_i_o">FileIO API</a>
to read and write files using a local secure data store.</p>
<p>You might use the File IO API with the URL Loading APIs to create an overall
data download and caching solution for your NaCl applications. For example:</p>
<ol class="arabic simple">
<li>Use the File IO APIs to check the local disk to see if a file exists that
your program needs.</li>
<li>If the file exists locally, load it into memory using the File IO API. If
the file doesn&#8217;t exist locally, use the URL Loading API to retrieve the
file from the server.</li>
<li>Use the File IO API to write the file to disk.</li>
<li>Load the file into memory using the File IO API when needed by your
application.</li>
</ol>
<p>The example discussed in this chapter is included in the SDK in the directory
<code>examples/api/file_io</code>.</p>
</section><section id="reference-information">
<h2 id="reference-information">Reference information</h2>
<p>For reference information related to FileIO, see the following documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/file__io_8h">file_io.h</a> - API
to create a FileIO object</li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/file__ref_8h">file_ref.h</a> - API
to create a file reference or &#8220;weak pointer&#8221; to a file in a file system</li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/file__system_8h">file_system.h</a> -
API to create a file system associated with a file</li>
</ul>
</section><section id="local-file-i-o">
<h2 id="local-file-i-o">Local file I/O</h2>
<p>Chrome provides an obfuscated, restricted area on disk to which a web app can
safely <a class="reference external" href="https://developers.google.com/chrome/whitepapers/storage#persistent">read and write files</a>. The
Pepper FileIO, FileRef, and FileSystem APIs (collectively called the File IO
APIs) allow you to access this sandboxed local disk so you can read and write
files and manage caching yourself. The data is persistent between launches of
Chrome, and is not removed unless your application deletes it or the user
manually deletes it. There is no limit to the amount of local data you can
use, other than the actual space available on the local drive.</p>
<section id="enabling-local-file-i-o">
<span id="enabling-file-access"></span><span id="quota-management"></span><h3 id="enabling-local-file-i-o"><span id="enabling-file-access"></span><span id="quota-management"></span>Enabling local file I/O</h3>
<p>The easiest way to enable the writing of persistent local data is to include
the <a class="reference external" href="http://developer.chrome.com/extensions/declare_permissions.html#unlimitedStorage">unlimitedStorage permission</a>
in your Chrome Web Store manifest file. With this permission you can use the
Pepper FileIO API without the need to request disk space at run time. When
the user installs the app Chrome displays a message announcing that the app
writes to the local disk.</p>
<p>If you do not use the <code>unlimitedStorage</code> permission you must include
JavaScript code that calls the <a class="reference external" href="http://updates.html5rocks.com/2011/11/Quota-Management-API-Fast-Facts">HTML5 Quota Management API</a> to
explicitly request local disk space before using the FileIO API. In this case
Chrome will prompt the user to accept a requestQuota call every time one is
made.</p>
</section><section id="testing-local-file-i-o">
<h3 id="testing-local-file-i-o">Testing local file I/O</h3>
<p>You should be aware that using the <code>unlimitedStorage</code> manifest permission
constrains the way you can test your app. Three of the four techniques
described in <a class="reference internal" href="/native-client/devguide/devcycle/running.html"><em>Running Native Client Applications</em></a>
read the Chrome Web Store manifest file and enable the <code>unlimitedStorage</code>
permission when it appears, but the first technique (local server) does not.
If you want to test the file IO portion of your app with a simple local server,
you need to include JavaScript code that calls the HTML5 Quota Management API.
When you deliver your application you can replace this code with the
<code>unlimitedStorage</code> manifest permission.</p>
</section></section><section id="the-file-io-example">
<h2 id="the-file-io-example">The <code>file_io</code> example</h2>
<p>The Native Client SDK includes an example, <code>file_io</code>, that demonstrates how
to read and write a local disk file. Since you will probably run the example
from a local server without a Chrome Web Store manifest file, the example&#8217;s
index file uses JavaScript to perform the Quota Management setup as described
above. The example has these primary files:</p>
<ul class="small-gap">
<li><code>index.html</code> - The HTML code that launches the Native Client module and
displays the user interface.</li>
<li><code>example.js</code> - JavaScript code that requests quota (as described above). It
also listens for user interaction with the user interface, and forwards the
requests to the Native Client module.</li>
<li><code>file_io.cc</code> - The code that sets up and provides an entry point to the
Native Client module.</li>
</ul>
<p>The remainder of this section covers the code in the <code>file_io.cc</code> file for
reading and writing files.</p>
<section id="file-i-o-overview">
<h3 id="file-i-o-overview">File I/O overview</h3>
<p>Like many Pepper APIs, the File IO API includes a set of methods that execute
asynchronously and that invoke callback functions in your Native Client module.
Unlike most other examples, the <code>file_io</code> example also demonstrates how to
make Pepper calls synchronously on a worker thread.</p>
<p>It is illegal to make blocking calls to Pepper on the module&#8217;s main thread.
This restriction is lifted when running on a worker thread&#8212;this is called
&#8220;calling Pepper off the main thread&#8221;. This often simplifies the logic of your
code; multiple asynchronous Pepper functions can be called from one function on
your worker thread, so you can use the stack and standard control flow
structures normally.</p>
<p>The high-level flow for the <code>file_io</code> example is described below. Note that
methods in the namespace <code>pp</code> are part of the Pepper C++ API.</p>
</section><section id="creating-and-writing-a-file">
<h3 id="creating-and-writing-a-file">Creating and writing a file</h3>
<p>Following are the high-level steps involved in creating and writing to a
file:</p>
<ol class="arabic simple">
<li><code>pp::FileIO::Open</code> is called with the <code>PP_FILEOPEN_FLAG_CREATE</code> flag to
create a file. Because the callback function is <code>pp::BlockUntilComplete</code>,
this thread is blocked until <code>Open</code> succeeds or fails.</li>
<li><code>pp::FileIO::Write</code> is called to write the contents. Again, the thread is
blocked until the call to <code>Write</code> completes. If there is more data to
write, <code>Write</code> is called again.</li>
<li>When there is no more data to write, call <code>pp::FileIO::Flush</code>.</li>
</ol>
</section><section id="opening-and-reading-a-file">
<h3 id="opening-and-reading-a-file">Opening and reading a file</h3>
<p>Following are the high-level steps involved in opening and reading a file:</p>
<ol class="arabic simple">
<li><code>pp::FileIO::Open</code> is called to open the file. Because the callback
function is <code>pp::BlockUntilComplete</code>, this thread is blocked until Open
succeeds or fails.</li>
<li><code>pp::FileIO::Query</code> is called to query information about the file, such as
its file size. The thread is blocked until <code>Query</code> completes.</li>
<li><code>pp::FileIO::Read</code> is called to read the contents. The thread is blocked
until <code>Read</code> completes. If there is more data to read, <code>Read</code> is called
again.</li>
</ol>
</section><section id="deleting-a-file">
<h3 id="deleting-a-file">Deleting a file</h3>
<p>Deleting a file is straightforward: call <code>pp::FileRef::Delete</code>. The thread is
blocked until <code>Delete</code> completes.</p>
</section><section id="making-a-directory">
<h3 id="making-a-directory">Making a directory</h3>
<p>Making a directory is also straightforward: call <code>pp::File::MakeDirectory</code>.
The thread is blocked until <code>MakeDirectory</code> completes.</p>
</section><section id="listing-the-contents-of-a-directory">
<h3 id="listing-the-contents-of-a-directory">Listing the contents of a directory</h3>
<p>Following are the high-level steps involved in listing a directory:</p>
<ol class="arabic simple">
<li><code>pp::FileRef::ReadDirectoryEntries</code> is called, and given a directory entry
to list. A callback is given as well; many of the other functions use
<code>pp::BlockUntilComplete</code>, but <code>ReadDirectoryEntries</code> returns results in
its callback, so it must be specified.</li>
<li>When the call to <code>ReadDirectoryEntries</code> completes, it calls
<code>ListCallback</code> which packages up the results into a string message, and
sends it to JavaScript.</li>
</ol>
</section></section><section id="file-io-deep-dive">
<h2 id="file-io-deep-dive"><code>file_io</code> deep dive</h2>
<p>The <code>file_io</code> example displays a user interface with a couple of fields and
several buttons. Following is a screenshot of the <code>file_io</code> example:</p>
<img alt="/native-client/images/fileioexample.png" src="/native-client/images/fileioexample.png" />
<p>Each radio button is a file operation you can perform, with some reasonable
default values for filenames. Try typing a message in the large input box and
clicking <code>Save</code>, then switching to the <code>Load File</code> operation, and
clicking <code>Load</code>.</p>
<p>Let&#8217;s take a look at what is going on under the hood.</p>
<section id="opening-a-file-system-and-preparing-for-file-i-o">
<h3 id="opening-a-file-system-and-preparing-for-file-i-o">Opening a file system and preparing for file I/O</h3>
<p><code>pp::Instance::Init</code> is called when an instance of a module is created. In
this example, <code>Init</code> starts a new thread (via the <code>pp::SimpleThread</code>
class), and tells it to open the filesystem:</p>
<pre class="prettyprint">
virtual bool Init(uint32_t /*argc*/,
const char * /*argn*/ [],
const char * /*argv*/ []) {
file_thread_.Start();
// Open the file system on the file_thread_. Since this is the first
// operation we perform there, and because we do everything on the
// file_thread_ synchronously, this ensures that the FileSystem is open
// before any FileIO operations execute.
file_thread_.message_loop().PostWork(
callback_factory_.NewCallback(&amp;FileIoInstance::OpenFileSystem));
return true;
}
</pre>
<p>When the file thread starts running, it will call <code>OpenFileSystem</code>. This
calls <code>pp::FileSystem::Open</code> and blocks the file thread until the function
returns.</p>
<aside class="note">
Note that the call to <code>pp::FileSystem::Open</code> uses
<code>pp::BlockUntilComplete</code> as its callback. This is only possible because we
are running off the main thread; if you try to make a blocking call from the
main thread, the function will return the error
<code>PP_ERROR_BLOCKS_MAIN_THREAD</code>.
</aside>
<pre class="prettyprint">
void OpenFileSystem(int32_t /*result*/) {
int32_t rv = file_system_.Open(1024 * 1024, pp::BlockUntilComplete());
if (rv == PP_OK) {
file_system_ready_ = true;
// Notify the user interface that we're ready
PostMessage(&quot;READY|&quot;);
} else {
ShowErrorMessage(&quot;Failed to open file system&quot;, rv);
}
}
</pre>
</section><section id="handling-messages-from-javascript">
<h3 id="handling-messages-from-javascript">Handling messages from JavaScript</h3>
<p>When you click the <code>Save</code> button, JavaScript posts a message to the NaCl
module with the file operation to perform sent as a string (See <a class="reference internal" href="/native-client/devguide/coding/message-system.html"><em>Messaging
System</em></a> for more details on message passing). The string is
parsed by <code>HandleMessage</code>, and new work is added to the file thread:</p>
<pre class="prettyprint">
virtual void HandleMessage(const pp::Var&amp; var_message) {
if (!var_message.is_string())
return;
// Parse message into: instruction file_name_length file_name [file_text]
std::string message = var_message.AsString();
std::string instruction;
std::string file_name;
std::stringstream reader(message);
int file_name_length;
reader &gt;&gt; instruction &gt;&gt; file_name_length;
file_name.resize(file_name_length);
reader.ignore(1); // Eat the delimiter
reader.read(&amp;file_name[0], file_name_length);
...
// Dispatch the instruction
if (instruction == kLoadPrefix) {
file_thread_.message_loop().PostWork(
callback_factory_.NewCallback(&amp;FileIoInstance::Load, file_name));
} else if (instruction == kSavePrefix) {
...
}
}
</pre>
</section><section id="saving-a-file">
<h3 id="saving-a-file">Saving a file</h3>
<p><code>FileIoInstance::Save</code> is called when the <code>Save</code> button is pressed. First,
it checks to see that the FileSystem has been successfully opened:</p>
<pre class="prettyprint">
if (!file_system_ready_) {
ShowErrorMessage(&quot;File system is not open&quot;, PP_ERROR_FAILED);
return;
}
</pre>
<p>It then creates a <code>pp::FileRef</code> resource with the name of the file. A
<code>FileRef</code> resource is a weak reference to a file in the FileSystem; that is,
a file can still be deleted even if there are outstanding <code>FileRef</code>
resources.</p>
<pre class="prettyprint">
pp::FileRef ref(file_system_, file_name.c_str());
</pre>
<p>Next, a <code>pp::FileIO</code> resource is created and opened. The call to
<code>pp::FileIO::Open</code> passes <code>PP_FILEOPEFLAG_WRITE</code> to open the file for
writing, <code>PP_FILEOPENFLAG_CREATE</code> to create a new file if it doesn&#8217;t already
exist and <code>PP_FILEOPENFLAG_TRUNCATE</code> to clear the file of any previous
content:</p>
<pre class="prettyprint">
pp::FileIO file(this);
int32_t open_result =
file.Open(ref,
PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE |
PP_FILEOPENFLAG_TRUNCATE,
pp::BlockUntilComplete());
if (open_result != PP_OK) {
ShowErrorMessage(&quot;File open for write failed&quot;, open_result);
return;
}
</pre>
<p>Now that the file is opened, it is written to in chunks. In an asynchronous
model, this would require writing a separate function, storing the current
state on the free store and a chain of callbacks. Because this function is
called off the main thread, <code>pp::FileIO::Write</code> can be called synchronously
and a conventional do/while loop can be used:</p>
<pre class="prettyprint">
int64_t offset = 0;
int32_t bytes_written = 0;
do {
bytes_written = file.Write(offset,
file_contents.data() + offset,
file_contents.length(),
pp::BlockUntilComplete());
if (bytes_written &gt; 0) {
offset += bytes_written;
} else {
ShowErrorMessage(&quot;File write failed&quot;, bytes_written);
return;
}
} while (bytes_written &lt; static_cast&lt;int64_t&gt;(file_contents.length()));
</pre>
<p>Finally, the file is flushed to push all changes to disk:</p>
<pre class="prettyprint">
int32_t flush_result = file.Flush(pp::BlockUntilComplete());
if (flush_result != PP_OK) {
ShowErrorMessage(&quot;File fail to flush&quot;, flush_result);
return;
}
</pre>
</section><section id="loading-a-file">
<h3 id="loading-a-file">Loading a file</h3>
<p><code>FileIoInstance::Load</code> is called when the <code>Load</code> button is pressed. Like
the <code>Save</code> function, <code>Load</code> first checks to see if the FileSystem has been
successfully opened, and creates a new <code>FileRef</code>:</p>
<pre class="prettyprint">
if (!file_system_ready_) {
ShowErrorMessage(&quot;File system is not open&quot;, PP_ERROR_FAILED);
return;
}
pp::FileRef ref(file_system_, file_name.c_str());
</pre>
<p>Next, <code>Load</code> creates and opens a new <code>FileIO</code> resource, passing
<code>PP_FILEOPENFLAG_READ</code> to open the file for reading. The result is compared
to <code>PP_ERROR_FILENOTFOUND</code> to give a better error message when the file
doesn&#8217;t exist:</p>
<pre class="prettyprint">
int32_t open_result =
file.Open(ref, PP_FILEOPENFLAG_READ, pp::BlockUntilComplete());
if (open_result == PP_ERROR_FILENOTFOUND) {
ShowErrorMessage(&quot;File not found&quot;, open_result);
return;
} else if (open_result != PP_OK) {
ShowErrorMessage(&quot;File open for read failed&quot;, open_result);
return;
}
</pre>
<p>Then <code>Load</code> calls <code>pp::FileIO::Query</code> to get metadata about the file, such
as its size. This is used to allocate a <code>std::vector</code> buffer that holds the
data from the file in memory:</p>
<pre class="prettyprint">
int32_t query_result = file.Query(&amp;info, pp::BlockUntilComplete());
if (query_result != PP_OK) {
ShowErrorMessage(&quot;File query failed&quot;, query_result);
return;
}
...
std::vector&lt;char&gt; data(info.size);
</pre>
<p>Similar to <code>Save</code>, a conventional while loop is used to read the file into
the newly allocated buffer:</p>
<pre class="prettyprint">
int64_t offset = 0;
int32_t bytes_read = 0;
int32_t bytes_to_read = info.size;
while (bytes_to_read &gt; 0) {
bytes_read = file.Read(offset,
&amp;data[offset],
data.size() - offset,
pp::BlockUntilComplete());
if (bytes_read &gt; 0) {
offset += bytes_read;
bytes_to_read -= bytes_read;
} else if (bytes_read &lt; 0) {
// If bytes_read &lt; PP_OK then it indicates the error code.
ShowErrorMessage(&quot;File read failed&quot;, bytes_read);
return;
}
}
</pre>
<p>Finally, the contents of the file are sent back to JavaScript, to be displayed
on the page. This example uses &#8220;<code>DISP|</code>&#8221; as a prefix command for display
information:</p>
<pre class="prettyprint">
std::string string_data(data.begin(), data.end());
PostMessage(&quot;DISP|&quot; + string_data);
ShowStatusMessage(&quot;Load success&quot;);
</pre>
</section><section id="id1">
<h3 id="id1">Deleting a file</h3>
<p><code>FileIoInstance::Delete</code> is called when the <code>Delete</code> button is pressed.
First, it checks whether the FileSystem has been opened, and creates a new
<code>FileRef</code>:</p>
<pre class="prettyprint">
if (!file_system_ready_) {
ShowErrorMessage(&quot;File system is not open&quot;, PP_ERROR_FAILED);
return;
}
pp::FileRef ref(file_system_, file_name.c_str());
</pre>
<p>Unlike <code>Save</code> and <code>Load</code>, <code>Delete</code> is called on the <code>FileRef</code> resource,
not a <code>FileIO</code> resource. Note that the result is checked for
<code>PP_ERROR_FILENOTFOUND</code> to give a better error message when trying to delete
a non-existent file:</p>
<pre class="prettyprint">
int32_t result = ref.Delete(pp::BlockUntilComplete());
if (result == PP_ERROR_FILENOTFOUND) {
ShowStatusMessage(&quot;File/Directory not found&quot;);
return;
} else if (result != PP_OK) {
ShowErrorMessage(&quot;Deletion failed&quot;, result);
return;
}
</pre>
</section><section id="listing-files-in-a-directory">
<h3 id="listing-files-in-a-directory">Listing files in a directory</h3>
<p><code>FileIoInstance::List</code> is called when the <code>List Directory</code> button is
pressed. Like all other operations, it checks whether the FileSystem has been
opened and creates a new <code>FileRef</code>:</p>
<pre class="prettyprint">
if (!file_system_ready_) {
ShowErrorMessage(&quot;File system is not open&quot;, PP_ERROR_FAILED);
return;
}
pp::FileRef ref(file_system_, dir_name.c_str());
</pre>
<p>Unlike the other operations, it does not make a blocking call to
<code>pp::FileRef::ReadDirectoryEntries</code>. Since <code>ReadDirectoryEntries</code> returns
the resulting directory entries in its callback, a new callback object is
created pointing to <code>FileIoInstance::ListCallback</code>.</p>
<p>The <code>pp::CompletionCallbackFactory</code> template class is used to instantiate a
new callback. Notice that the <code>FileRef</code> resource is passed as a parameter;
this will add a reference count to the callback object, to keep the <code>FileRef</code>
resource from being destroyed when the function finishes.</p>
<pre class="prettyprint">
// Pass ref along to keep it alive.
ref.ReadDirectoryEntries(callback_factory_.NewCallbackWithOutput(
&amp;FileIoInstance::ListCallback, ref));
</pre>
<p><code>FileIoInstance::ListCallback</code> then gets the results passed as a
<code>std::vector</code> of <code>pp::DirectoryEntry</code> objects, and sends them to
JavaScript:</p>
<pre class="prettyprint">
void ListCallback(int32_t result,
const std::vector&lt;pp::DirectoryEntry&gt;&amp; entries,
pp::FileRef /*unused_ref*/) {
if (result != PP_OK) {
ShowErrorMessage(&quot;List failed&quot;, result);
return;
}
std::stringstream ss;
ss &lt;&lt; &quot;LIST&quot;;
for (size_t i = 0; i &lt; entries.size(); ++i) {
pp::Var name = entries[i].file_ref().GetName();
if (name.is_string()) {
ss &lt;&lt; &quot;|&quot; &lt;&lt; name.AsString();
}
}
PostMessage(ss.str());
ShowStatusMessage(&quot;List success&quot;);
}
</pre>
</section><section id="making-a-new-directory">
<h3 id="making-a-new-directory">Making a new directory</h3>
<p><code>FileIoInstance::MakeDir</code> is called when the <code>Make Directory</code> button is
pressed. Like all other operations, it checks whether the FileSystem has been
opened and creates a new <code>FileRef</code>:</p>
<pre class="prettyprint">
if (!file_system_ready_) {
ShowErrorMessage(&quot;File system is not open&quot;, PP_ERROR_FAILED);
return;
}
pp::FileRef ref(file_system_, dir_name.c_str());
</pre>
<p>Then the <code>pp::FileRef::MakeDirectory</code> function is called.</p>
<pre class="prettyprint">
int32_t result = ref.MakeDirectory(
PP_MAKEDIRECTORYFLAG_NONE, pp::BlockUntilComplete());
if (result != PP_OK) {
ShowErrorMessage(&quot;Make directory failed&quot;, result);
return;
}
ShowStatusMessage(&quot;Make directory success&quot;);
</pre>
</section></section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,10 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="coding-your-application">
<span id="coding"></span><h1 id="coding-your-application"><span id="coding"></span>Coding Your Application</h1>
<p>This section of the Developer&#8217;s Guide describes important concepts that would be
useful to understand in order to code your application&#8212;e.g., how an
application is structured, and how to use the Pepper APIs.</p>
</section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,376 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="messaging-system">
<span id="message-system"></span><h1 id="messaging-system"><span id="message-system"></span>Messaging System</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#reference-information" id="id2">Reference information</a></li>
<li><p class="first"><a class="reference internal" href="#introduction-to-the-messaging-system" id="id3">Introduction to the messaging system</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#design-of-the-messaging-system" id="id4">Design of the messaging system</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#communication-tasks-in-the-hello-world-example" id="id5">Communication tasks in the &#8220;Hello, World&#8221; example</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#javascript-code" id="id6">JavaScript code</a></li>
<li><a class="reference internal" href="#native-client-module" id="id7">Native Client module</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#messaging-in-javascript-code-more-details" id="id8">Messaging in JavaScript code: More details.</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#setting-up-an-event-listener-and-handler" id="id9">Setting up an event listener and handler</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#messaging-in-the-native-client-module-more-details" id="id10">Messaging in the Native Client module: More details.</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#implementing-handlemessage" id="id11">Implementing HandleMessage()</a></li>
<li><a class="reference internal" href="#implementing-application-specific-functions" id="id12">Implementing application-specific functions</a></li>
<li><a class="reference internal" href="#sending-messages-back-to-the-javascript-code" id="id13">Sending messages back to the JavaScript code</a></li>
<li><a class="reference internal" href="#sending-and-receiving-other-pp-var-types" id="id14">Sending and receiving other <code>pp::Var</code> types</a></li>
</ul>
</li>
</ul>
</div>
<p>This chapter describes the messaging system used to communicate between the
JavaScript code and the Native Client module&#8217;s C or C++ code in a
Native Client application. It introduces the concept of asynchronous
programming and the basic steps required to set up a Native Client module
that sends messages to and receive messages from JavaScript. This chapter
assumes you are familiar with the material presented in the
<a class="reference internal" href="/native-client/devguide/coding/application-structure.html"><em>Application Structure</em></a> chapter.</p>
<aside class="note">
The &#8220;Hello, World&#8221; example for getting started with NaCl is used here to
illustrate basic programming techniques. You can find this code in
the <code>/getting_started/part2</code> directory in the Native Client SDK download.
</aside>
<section id="reference-information">
<h2 id="reference-information">Reference information</h2>
<p>For reference information related to the Pepper messaging API, see the
following documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_instance">pp::Instance class</a> HandleMessage(), PostMessage())</li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_module">pp::Module class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_var">pp::Var class</a></li>
</ul>
</section><section id="introduction-to-the-messaging-system">
<h2 id="introduction-to-the-messaging-system">Introduction to the messaging system</h2>
<p>Native Client modules and JavaScript communicate by sending messages
to each other. The most basic form of a message is a string. Messages
support many JavaScript types, including ints, arrays, array buffers,
and dictionaries (see <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_var">pp::Var</a>,
<a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_var_array_buffer">pp:VarArrayBuffer</a>,
and the general <a class="reference external" href="https://developers.google.com/native-client/pepperc/struct_p_p_b___messaging__1__0">messaging system documentation</a>).
It&#8217;s up to you to decide on the type of message and define how to
process the messages on both the JavaScript and Native Client
side. For the &#8220;Hello, World&#8221; example, we will work with string-typed
messages only.</p>
<p>When JavaScript posts a message to the Native Client module, the
Pepper <code>HandleMessage()</code> function is invoked on the module
side. Similarly, the Native Client module can post a message to
JavaScript, and this message triggers a JavaScript event listener for
<code>message</code> events in the DOM. (See the W3C specification on
<a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html">Document Object Model Events</a> for more
information.) In the &#8220;Hello, World&#8221; example, the JavaScript functions for
posting and handling messages are named <code>postMessage()</code> and
<code>handleMessage()</code> (but any names could be used). On the Native Client
C++ side, the Pepper Library functions for posting and handling
messages are:</p>
<ul class="small-gap">
<li><code>void pp::Instance::PostMessage(const Var &amp;message)</code></li>
<li><code>virtual void pp::Instance::HandleMessage(const Var &amp;message)</code></li>
</ul>
<p>If you want to receive messages from JavaScript, you need to implement the
<code>pp::Instance::HandleMessage()</code> function in your Native Client module.</p>
<section id="design-of-the-messaging-system">
<h3 id="design-of-the-messaging-system">Design of the messaging system</h3>
<p>The Native Client messaging system is analogous to the system used by
the browser to allow web workers to communicate (see the <a class="reference external" href="http://www.w3.org/TR/workers">W3 web
worker specification</a>). The Native
Client messaging system is designed to keep the web page responsive while the
Native Client module is performing potentially heavy processing in the
background. When JavaScript sends a message to the Native Client
module, the <code>postMessage()</code> call returns as soon as it sends its message
to the Native Client module. The JavaScript does not wait for a reply
from Native Client, thus avoiding bogging down the main JavaScript
thread. On the JavaScript side, you set up an event listener to
respond to the message sent by the Native Client module when it has
finished the requested processing and returns a message.</p>
<p>This asynchronous processing model keeps the main thread free while
avoiding the following problems:</p>
<ul class="small-gap">
<li>The JavaScript engine hangs while waiting for a synchronous call to return.</li>
<li>The browser pops up a dialog when a JavaScript entry point takes longer
than a few moments.</li>
<li>The application hangs while waiting for an unresponsive Native Client module.</li>
</ul>
</section></section><section id="communication-tasks-in-the-hello-world-example">
<h2 id="communication-tasks-in-the-hello-world-example">Communication tasks in the &#8220;Hello, World&#8221; example</h2>
<p>The following sections describe how the &#8220;Hello, World&#8221; example posts
and handles messages on both the JavaScript side and the Native Client
side of the application.</p>
<section id="javascript-code">
<h3 id="javascript-code">JavaScript code</h3>
<p>The JavaScript code and HTML in the &#8220;Hello, World&#8221; example can be
found in the <code>example.js</code>, <code>common.js</code>, and <code>index.html</code> files.
The important steps are:</p>
<ol class="arabic simple">
<li>Sets up an event listener to listen for <code>message</code> events from the
Native Client module.</li>
<li>Implements an event handler that the event listener invokes to handle
incoming <code>message</code> events.</li>
<li>Calls <code>postMessage()</code> to communicate with the NaCl module,
after the page loads.</li>
</ol>
<section id="step-1-from-common-js">
<h4 id="step-1-from-common-js">Step 1: From common.js</h4>
<pre class="prettyprint">
function attachDefaultListeners() {
// The NaCl module embed is created within the listenerDiv
var listenerDiv = document.getElementById('listener');
// ...
// register the handleMessage function as the message event handler.
listenerDiv.addEventListener('message', handleMessage, true);
// ...
}
</pre>
</section><section id="step-2-from-example-js">
<h4 id="step-2-from-example-js">Step 2: From example.js</h4>
<pre class="prettyprint">
// This function is called by common.js when a message is received from the
// NaCl module.
function handleMessage(message) {
// In the example, we simply log the data that's received in the message.
var logEl = document.getElementById('log');
logEl.textContent += message.data;
}
// In the index.html we have set up the appropriate divs:
&lt;body {attrs}&gt;
&lt;!-- ... --&gt;
&lt;div id=&quot;listener&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;log&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
</pre>
</section><section id="step-3-from-example-js">
<h4 id="step-3-from-example-js">Step 3: From example.js</h4>
<pre class="prettyprint">
// From example.js, Step 3:
function moduleDidLoad() {
// After the NaCl module has loaded, common.naclModule is a reference to the
// NaCl module's &lt;embed&gt; element.
//
// postMessage sends a message to it.
common.naclModule.postMessage('hello');
}
</pre>
</section></section><section id="native-client-module">
<h3 id="native-client-module">Native Client module</h3>
<p>The C++ code in the Native Client module of the &#8220;Hello, World&#8221; example:</p>
<ol class="arabic simple">
<li>Implements <code>pp::Instance::HandleMessage()</code> to handle messages sent
by the JavaScript.</li>
<li>Processes incoming messages. This example simply checks that JavaScript
has sent a &#8220;hello&#8221; message and not some other message.</li>
<li>Calls <code>PostMessage()</code> to send an acknowledgement back to the
JavaScript code. The acknowledgement is a string in the form of a <code>Var</code>
that the JavaScript code can process. In general, a <code>pp::Var</code> can be
several JavaScript types, see the
<a class="reference external" href="https://developers.google.com/native-client/pepperc/struct_p_p_b___messaging__1__0">messaging system documentation</a>.</li>
</ol>
<pre class="prettyprint">
class HelloTutorialInstance : public pp::Instance {
public:
// ...
// === Step 1: Implement the HandleMessage function. ===
virtual void HandleMessage(const pp::Var&amp; var_message) {
// === Step 2: Process the incoming message. ===
// Ignore the message if it is not a string.
if (!var_message.is_string())
return;
// Get the string message and compare it to &quot;hello&quot;.
std::string message = var_message.AsString();
if (message == kHelloString) {
// === Step 3: Send the reply. ===
// If it matches, send our response back to JavaScript.
pp::Var var_reply(kReplyString);
PostMessage(var_reply);
}
}
};
</pre>
</section></section><section id="messaging-in-javascript-code-more-details">
<h2 id="messaging-in-javascript-code-more-details">Messaging in JavaScript code: More details.</h2>
<p>This section describes in more detail the messaging system code in the
JavaScript portion of the &#8220;Hello, World&#8221; example.</p>
<section id="setting-up-an-event-listener-and-handler">
<h3 id="setting-up-an-event-listener-and-handler">Setting up an event listener and handler</h3>
<p>The following JavaScript code sets up an event listener for messages
posted by the Native Client module. It then defines a message handler
that simply logs the content of messages received from the module.</p>
<section id="setting-up-the-message-handler-on-load">
<h4 id="setting-up-the-message-handler-on-load">Setting up the &#8216;message&#8217; handler on load</h4>
<pre class="prettyprint">
// From common.js
// Listen for the DOM content to be loaded. This event is fired when
// parsing of the page's document has finished.
document.addEventListener('DOMContentLoaded', function() {
var body = document.body;
// ...
var loadFunction = common.domContentLoaded;
// ... set up parameters ...
loadFunction(...);
}
// This function is exported as common.domContentLoaded.
function domContentLoaded(...) {
// ...
if (common.naclModule == null) {
// ...
attachDefaultListeners();
// initialize common.naclModule ...
} else {
// ...
}
}
function attachDefaultListeners() {
var listenerDiv = document.getElementById('listener');
// ...
listenerDiv.addEventListener('message', handleMessage, true);
// ...
}
</pre>
</section><section id="implementing-the-handler">
<h4 id="implementing-the-handler">Implementing the handler</h4>
<pre class="prettyprint">
// From example.js
function handleMessage(message) {
var logEl = document.getElementById('log');
logEl.textContent += message.data;
}
</pre>
<p>Note that the <code>handleMessage()</code> function is handed a message_event
containing <code>data</code> that you can display or manipulate in JavaScript. The
&#8220;Hello, World&#8221; application simply logs this data to the <code>log</code> div.</p>
</section></section></section><section id="messaging-in-the-native-client-module-more-details">
<h2 id="messaging-in-the-native-client-module-more-details">Messaging in the Native Client module: More details.</h2>
<p>This section describes in more detail the messaging system code in
the Native Client module portion of the &#8220;Hello, World&#8221; example.</p>
<section id="implementing-handlemessage">
<h3 id="implementing-handlemessage">Implementing HandleMessage()</h3>
<p>If you want the Native Client module to receive and handle messages
from JavaScript, you need to implement a <code>HandleMessage()</code> function
for your module&#8217;s <code>pp::Instance</code> class. The
<code>HelloWorldInstance::HandleMessage()</code> function examines the message
posted from JavaScript. First it examines that the type of the
<code>pp::Var</code> is indeed a string (not a double, etc.). It then
interprets the data as a string with <code>var_message.AsString()</code>, and
checks that the string matches <code>kHelloString</code>. After examining the
message received from JavaScript, the code calls <code>PostMessage()</code> to
send a reply message back to the JavaScript side.</p>
<pre class="prettyprint">
namespace {
// The expected string sent by the JavaScript.
const char* const kHelloString = &quot;hello&quot;;
// The string sent back to the JavaScript code upon receipt of a message
// containing &quot;hello&quot;.
const char* const kReplyString = &quot;hello from NaCl&quot;;
} // namespace
class HelloTutorialInstance : public pp::Instance {
public:
// ...
virtual void HandleMessage(const pp::Var&amp; var_message) {
// Ignore the message if it is not a string.
if (!var_message.is_string())
return;
// Get the string message and compare it to &quot;hello&quot;.
std::string message = var_message.AsString();
if (message == kHelloString) {
// If it matches, send our response back to JavaScript.
pp::Var var_reply(kReplyString);
PostMessage(var_reply);
}
}
};
</pre>
</section><section id="implementing-application-specific-functions">
<h3 id="implementing-application-specific-functions">Implementing application-specific functions</h3>
<p>While the &#8220;Hello, World&#8221; example is very simple, your Native Client
module will likely include application-specific functions to perform
custom tasks in response to messages. For example the application
could be a compression and decompression service (two functions
exported). The application could set up an application-specific
convention that messages coming from JavaScript are colon-separated
pairs of the form <code>&lt;command&gt;:&lt;data&gt;</code>. The Native Client module
message handler can then split the incoming string along the <code>:</code>
character to determine which command to execute. If the command is
&#8220;compress&#8221;, then data to process is an uncompressed string. If the
command is &#8220;uncompress&#8221;, then data to process is an already-compressed
string. After processing the data asynchronously, the application then
returns the result to JavaScript.</p>
</section><section id="sending-messages-back-to-the-javascript-code">
<h3 id="sending-messages-back-to-the-javascript-code">Sending messages back to the JavaScript code</h3>
<p>The Native Client module sends messages back to the JavaScript code
using <code>PostMessage()</code>. The Native Client module always returns
its values in the form of a <code>pp::Var</code> that can be processed by the
browser&#8217;s JavaScript. In this example, the message is posted at the
end of the Native Client module&#8217;s <code>HandleMessage()</code> function:</p>
<pre class="prettyprint">
PostMessage(var_reply);
</pre>
</section><section id="sending-and-receiving-other-pp-var-types">
<h3 id="sending-and-receiving-other-pp-var-types">Sending and receiving other <code>pp::Var</code> types</h3>
<p>Besides strings, <code>pp::Var</code> can represent other types of JavaScript
objects. For example, messages can be JavaScript objects. These
richer types can make it easier to implement an application&#8217;s
messaging protocol.</p>
<p>To send a dictionary from the NaCl module to JavaScript simply create
a <code>pp::VarDictionary</code> and then call <code>PostMessage</code> with the
dictionary.</p>
<pre class="prettyprint">
pp::VarDictionary dictionary;
dictionary.Set(pp::Var(&quot;command&quot;), pp::Var(next_command));
dictionary.Set(pp::Var(&quot;param_int&quot;), pp::Var(123));
pp::VarArray an_array;
an_array.Set(0, pp::Var(&quot;string0&quot;));
an_array.Set(1, pp::Var(&quot;string1&quot;))
dictionary.Set(pp::Var(&quot;param_array&quot;), an_array);
PostMessage(dictionary);
</pre>
<p>Here is how to create a similar object in JavaScript and send it to
the NaCl module:</p>
<pre class="prettyprint">
var dictionary = {
command: next_command,
param_int: 123,
param_array: ['string0', 'string1']
}
nacl_module.postMessage(dictionary);
</pre>
<p>To receive a dictionary-typed message in the NaCl module, test that
the message is truly a dictionary type, then convert the message
with the <code>pp::VarDictionary</code> class.</p>
<pre class="prettyprint">
virtual void HandleMessage(const pp::Var&amp; var) {
if (var.is_dictionary()) {
pp::VarDictionary dictionary(var);
// Use the dictionary
pp::VarArray keys = dictionary.GetKeys();
// ...
} else {
// ...
}
}
</pre>
</section></section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,225 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="the-nacl-io-library">
<span id="nacl-io"></span><h1 id="the-nacl-io-library"><span id="nacl-io"></span>The nacl_io Library</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
<li><a class="reference internal" href="#using-nacl-io" id="id2">Using nacl_io</a></li>
<li><p class="first"><a class="reference internal" href="#the-nacl-io-demo" id="id3">The nacl_io demo</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#building-and-running-the-demo" id="id4">Building and running the demo</a></li>
<li><a class="reference internal" href="#a-look-at-the-code" id="id5">A look at the code</a></li>
</ul>
</li>
<li><a class="reference internal" href="#reference-information" id="id6">Reference information</a></li>
</ul>
</div>
<section id="introduction">
<h2 id="introduction">Introduction</h2>
<p><code>nacl_io</code> is a utility library that provides implementations of standard
C APIs such as POSIX I/O (<code>stdio.h</code>) and BSD sockets (<code>sys/socket.h</code>).
Its primary function is to allow code that uses these standard APIs to be
compiled and used in a Native Client module. The library is included as part
of Native Client SDK and is implemented in on top of Pepper API.</p>
<p>Since Native Client modules cannot access the host machine&#8217;s file system
directly, nacl_io provides several alternative filesystem types which
can be used by the application. For example, the Chrome browser supports the
<a class="reference external" href="http://www.html5rocks.com/en/tutorials/file/filesystem/">HTML5 File System API</a> which provides
access to a protected area of the local file system. This filesystem can
be accessed by an HTML page using JavaScript commands, and also by a Native
Client module using the Pepper <a class="reference internal" href="/native-client/devguide/coding/file-io.html"><em>File IO API</em></a>. With nacl_io
a Native Client application can mount an HTML5 filesystem and access it via
standard POSIX I/O function such as <code>fopen</code>, <code>fseek</code>, <code>fread</code>,
<code>fwrite</code>, and <code>fclose</code>, or their low level UNIX counterparts <code>open</code>,
<code>lseek</code>, <code>read</code>, <code>write</code> and <code>close</code>.</p>
<p>As well as the HTML5 file system, nacl_io provides several other file system
types which are described in the table below:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">File System</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>memfs</td>
<td>An in-memory file system</td>
</tr>
<tr class="row-odd"><td>html5fs</td>
<td>An HTML5 local file system, which can be persistent or temporary</td>
</tr>
<tr class="row-even"><td>http</td>
<td>Maps files on a remote webserver into the local filesystem.</td>
</tr>
<tr class="row-odd"><td>dev</td>
<td>A file system containing special files (e.g.: <code>/dev/null</code>)</td>
</tr>
</tbody>
</table>
</section><section id="using-nacl-io">
<h2 id="using-nacl-io">Using nacl_io</h2>
<p>Using nacl_io is mostly just a matter of using the standard POSIX C library
functions. However, there are some steps required to initialize the library
and setup the filesystem mounts. In general the following steps will be needed
to use nacl_io in a NaCl application:</p>
<ol class="arabic simple">
<li>Link the application with the nacl_io library (<code>-lnacl_io</code>)</li>
<li>Initialize nacl_io at startup using the <code>nacl_io_init_ppapi</code> or
<code>nacl_io_init</code> functions.</li>
<li>Mount any desired filesystems using the <code>mount</code> function. The arguments
to <code>mount</code> for the different filesystem types are detailed in
<code>include/nacl_io/nacl_io.h</code>.</li>
<li>If you are going to mount an HTML5 file system, be sure to allocate space
for it. You can either set the <code>unlimitedStorage</code> permission in the app&#8217;s
Web Store manifest file, or call the HTML5 QuotaManagement API. These
options are explained in the <a class="reference internal" href="/native-client/devguide/coding/file-io.html#quota-management"><em>File IO documentation</em></a>.</li>
<li>Make sure that file and socket API calls are all made from the background
thread. This is because the main Pepper thread does not support the blocking
behavior needed by the POSIX I/O operations.</li>
</ol>
</section><section id="the-nacl-io-demo">
<h2 id="the-nacl-io-demo">The nacl_io demo</h2>
<section id="building-and-running-the-demo">
<h3 id="building-and-running-the-demo">Building and running the demo</h3>
<p>The demo application launches a Native Client module that mounts three file
systems and displays a set of controls that let you work with them:</p>
<img alt="/native-client/images/nacl_io1.png" src="/native-client/images/nacl_io1.png" />
<p>Follow these steps to build and run the demo:</p>
<ul class="small-gap">
<li><p class="first">Open a terminal in the demo directory:</p>
<pre class="prettyprint">
$ cd $NACL_SDK_ROOT/examples/demo/nacl_io
</pre>
</li>
<li><p class="first">run the demo:</p>
<pre class="prettyprint">
$ make run
</pre>
</li>
</ul>
<p>Once the demo is running, try these operations:</p>
<ol class="arabic simple">
<li>select the fopen command (when you select a command the fields in the line
below will change according to the command)</li>
<li>type in the filename <code>/persistent/test</code></li>
<li>check the write checkbox and press the fopen button</li>
<li>select the fwrite command and select the file <code>/persistent/test</code> in the
menu that appears below on the left</li>
<li>enter some data and press the fwrite button</li>
<li>select the fclose command, be sure the file <code>/persistent/test</code> is selected
in the menu, and press the fclose button</li>
<li>select the fopen command</li>
<li>type in the filename <code>/persistent/test</code></li>
<li>check the fread checkbox and press the fopen button</li>
<li>select the fread command, be sure the file /persistent/test is selected in
the menu, enter a byte count, and press the fread button</li>
</ol>
</section><section id="a-look-at-the-code">
<h3 id="a-look-at-the-code">A look at the code</h3>
<p>The demo is written C and comprises three files.</p>
<section id="nacl-io-demo-c">
<h4 id="nacl-io-demo-c">nacl_io_demo.c</h4>
<p>This is the demo&#8217;s main file. The code here creates and initializes the Native
Client module instance. The Pepper function <code>Instance_DidCreate</code> initializes
nacl_io and mounts an HTML5 filesystem at <code>/persistent</code>.</p>
<pre class="prettyprint">
static PP_Bool Instance_DidCreate(PP_Instance instance,
uint32_t argc,
const char* argn[],
const char* argv[]) {
g_instance = instance;
nacl_io_init_ppapi(instance, get_browser_interface);
mount(
&quot;&quot;, /* source */
&quot;/persistent&quot;, /* target */
&quot;html5fs&quot;, /* filesystemtype */
0, /* mountflags */
&quot;type=PERSISTENT,expected_size=1048576&quot;); /* data specific to the html5fs type */
pthread_create(&amp;g_handle_message_thread, NULL, &amp;HandleMessageThread, NULL);
InitializeMessageQueue();
return PP_TRUE;
}
</pre>
<p>Space is allocated to the <code>/persistent</code> file system after the module is
initialized. This is accomplished by the <code>domContentLoaded</code> function in
the file <code>example.js</code>. This script is included in the module&#8217;s html page (see
<code>examples/demo/index.html</code>):</p>
<pre class="prettyprint">
function domContentLoaded(name, tc, config, width, height) {
navigator.webkitPersistentStorage.requestQuota(window.PERSISTENT, 1024 * 1024,
function(bytes) {
common.updateStatus(
'Allocated ' + bytes + ' bytes of persistant storage.');
common.createNaClModule(name, tc, config, width, height);
common.attachDefaultListeners();
},
function(e) { alert('Failed to allocate space') });
}
</pre>
<p>The <code>Instance_DidCreate</code> function also creates a worker thread that receives
messages sent from the html page and performs the specified file system
operations. The logic for the worker thread is encoded in the other two files,
described below.</p>
</section><section id="queue-c">
<h4 id="queue-c">queue.c</h4>
<p>This file implements a circular queue that is used to receive messages from the
browser UI to the Native Client module. The file system commands in the
enqueued messages are executed on the worker thread. This keeps blocking calls
(like fread) off the main Native Client thread, which is a good thing. The
queue is initialized in nacl_io_demo.c <code>Instance_DidCreate</code>.</p>
</section><section id="handlers-c">
<h4 id="handlers-c">handlers.c</h4>
<p>This file implements the stdio calls associated with the commands sent from the
browser. There is a separate <code>Handle*</code> function for each command: fopen,
fclose, fseek, fread, fwrite. The handlers are called from the
<code>HandleMessage</code> function in nacl_io_demo.c, which runs in the worker
thread managing the message queue. The code for the <code>fwrite</code> handler appears
below. Notice that it does not contain any PPAPI calls and looks like
&#8220;ordinary&#8221; C code.</p>
<pre class="prettyprint">
int HandleFwrite(int num_params, char** params, char** output) {
FILE* file;
const char* file_index_string;
const char* data;
size_t data_len;
size_t bytes_written;
if (num_params != 2) {
*output = PrintfToNewString(&quot;Error: fwrite takes 2 parameters.&quot;);
return 1;
}
file_index_string = params[0];
file = GetFileFromIndexString(file_index_string, NULL);
data = params[1];
data_len = strlen(data);
if (!file) {
*output = PrintfToNewString(&quot;Error: Unknown file handle %s.&quot;,
file_index_string);
return 2;
}
bytes_written = fwrite(data, 1, data_len, file);
*output = PrintfToNewString(&quot;fwrite\1%s\1%d&quot;, file_index_string,
bytes_written);
return 0;
}
</pre>
</section></section></section><section id="reference-information">
<h2 id="reference-information">Reference information</h2>
<p>The example discussed here is included in the SDK in the directory
<code>examples/demo/nacl_io</code>.</p>
<p>The nacl_io library is included in the SDK toolchain and is not a part of the
Pepper API. For reference information related to the nacl_io interface see
its header file in the SDK directory, located at
<code>include/nacl_io/nacl_io.h</code>.</p>
<p>For more about the HTML5 file system read the <a class="reference external" href="http://dev.w3.org/2009/dap/file-system/pub/FileSystem/">specification</a>.</p>
</section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,178 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="native-client-modules">
<span id="devcycle-native-client-modules"></span><h1 id="native-client-modules"><span id="devcycle-native-client-modules"></span>Native Client Modules</h1>
<p>This document describes the classes and functions that you need to implement in
a Native Client module in order for Chrome to load, initialize, and run it. The
requirements are the same regardless of whether or not the module uses PNaCl,
but depend on whether the module is written in C or C++.</p>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#introduction" id="id2">Introduction</a></li>
<li><a class="reference internal" href="#writing-modules-in-c" id="id3">Writing modules in C</a></li>
<li><a class="reference internal" href="#id1" id="id4">Writing modules in C++</a></li>
</ul>
</div>
<section id="introduction">
<h2 id="introduction">Introduction</h2>
<p>Native Client modules do not have a <code>main()</code> function. When a module loads,
the Native Client runtime calls the code in the module to create an instance and
initialize the interfaces for the APIs the module uses. This initialization
sequence depends on whether the module is written in C or C++ and requires that
you implement specific functions in each case.</p>
</section><section id="writing-modules-in-c">
<h2 id="writing-modules-in-c">Writing modules in C</h2>
<p>The C API uses a prefix convention to show whether an interface is implemented
in the browser or in a module. Interfaces starting with <code>PPB_</code> (which can be
read as &#8220;Pepper <em>browser</em>&#8221;) are implemented in the browser and they are called
from your module. Interfaces starting with <code>PPP_</code> (&#8220;Pepper <em>plugin</em>&#8221;) are
implemented in the module; they are called from the browser and will execute on
the main thread of the module instance.</p>
<p>When you implement a Native Client module in C you must include these components:</p>
<ul class="small-gap">
<li>The functions <code>PPP_InitializeModule</code> and <code>PPP_GetInterface</code></li>
<li>Code that implements the interface <code>PPP_Instance</code> and any other C interfaces
that your module uses</li>
</ul>
<p>For each PPP interface, you must implement all of its functions, create the
struct through which the browser calls the interface, and insure that the
function <code>PPP_GetInterface</code> returns the appropriate struct for the interface.</p>
<p>For each PPB interface, you must declare a pointer to the interface and
initialize the pointer with a call to <code>get_browser</code> inside
<code>PPP_InitializeModule</code>.</p>
<p>These steps are illustrated in the code excerpt below, which shows the
implementation and initialization of the required <code>PPP_Instance</code>
interface. The code excerpt also shows the initialization of three additional
interfaces which are not required: <code>PPB_Instance</code> (through which the Native
Client module calls back to the browser) and <code>PPB_InputEvent</code> and
<code>PPP_InputEvent</code>.</p>
<pre class="prettyprint">
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &quot;ppapi/c/pp_errors.h&quot;
#include &quot;ppapi/c/ppp.h&quot;
// Include the interface headers.
// PPB APIs describe calls from the module to the browser.
// PPP APIs describe calls from the browser to the functions defined in your module.
#include &quot;ppapi/c/ppb_instance.h&quot;
#include &quot;ppapi/c/ppp_instance.h&quot;
#include &quot;ppapi/c/ppb_input_event.h&quot;
#include &quot;ppapi/c/ppp_input_event.h&quot;
// Create pointers for each PPB interface that your module uses.
static PPB_Instance* ppb_instance_interface = NULL;
static PPB_InputEvent* ppb_input_event_interface = NULL;
// Define all the functions for each PPP interface that your module uses.
// Here is a stub for the first function in PPP_Instance.
static PP_Bool Instance_DidCreate(PP_Instance instance,
uint32_t argc,
const char* argn[],
const char* argv[]) {
return PP_TRUE;
}
// ... more API functions ...
// Define PPP_GetInterface.
// This function should return a non-NULL value for every interface you are using.
// The string for the name of the interface is defined in the interface's header file.
// The browser calls this function to get pointers to the interfaces that your module implements.
PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
// Create structs for each PPP interface.
// Assign the interface functions to the data fields.
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
static PPP_Instance instance_interface = {
&amp;Instance_DidCreate,
// The definitions of these functions are not shown
&amp;Instance_DidDestroy,
&amp;Instance_DidChangeView,
&amp;Instance_DidChangeFocus,
&amp;Instance_HandleDocumentLoad
};
return &amp;instance_interface;
}
if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0) {
static PPP_InputEvent input_interface = {
// The definition of this function is not shown.
&amp;Instance_HandleInput,
};
return &amp;input_interface;
}
// Return NULL for interfaces that you do not implement.
return NULL;
}
// Define PPP_InitializeModule, the entry point of your module.
// Retrieve the API for the browser-side (PPB) interfaces you will use.
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) {
ppb_instance_interface = (PPB_Instance*)(get_browser(PPB_INSTANCE_INTERFACE));
ppb_input_event_interface = (PPB_InputEvent*)(get_browser(PPB_INPUT_EVENT_INTERFACE));
return PP_OK;
}
</pre>
</section><section id="id1">
<h2 id="id1">Writing modules in C++</h2>
<p>When you implement a Native Client module in C++ you must include these components:</p>
<ul class="small-gap">
<li>The factory function called <code>CreateModule()</code></li>
<li>Code that defines your own Module class (derived from the <code>pp::Module</code>
class)</li>
<li>Code that defines your own Instance class (derived from the <code>pp:Instance</code>
class)</li>
</ul>
<p>In the &#8220;Hello tutorial&#8221; example (in the <code>getting_started/part1</code> directory of
the NaCl SDK), these three components are specified in the file
<code>hello_tutorial.cc</code>. Here is the factory function:</p>
<pre class="prettyprint">
namespace pp {
Module* CreateModule() {
return new HelloTutorialModule();
}
}
</pre>
<p>The <code>CreateModule()</code> factory function is the main binding point between a
module and the browser, and serves as the entry point into the module. The
browser calls <code>CreateModule()</code> when a module is first loaded; this function
returns a Module object derived from the <code>pp::Module</code> class. The browser keeps
a singleton of the Module object.</p>
<p>Below is the Module class from the &#8220;Hello tutorial&#8221; example:</p>
<pre class="prettyprint">
class HelloTutorialModule : public pp::Module {
public:
HelloTutorialModule() : pp::Module() {}
virtual ~HelloTutorialModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new HelloTutorialInstance(instance);
}
};
</pre>
<p>The Module class must include a <code>CreateInstance()</code> method. The browser calls
the <code>CreateInstance()</code> method every time it encounters an <code>&lt;embed&gt;</code> element
on a web page that references the same module. The <code>CreateInstance()</code> function
creates and returns an Instance object derived from the <code>pp::Instance</code> class.</p>
<p>Below is the Instance class from the &#8220;Hello tutorial&#8221; example:</p>
<pre class="prettyprint">
class HelloTutorialInstance : public pp::Instance {
public:
explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance) {}
virtual ~HelloTutorialInstance() {}
virtual void HandleMessage(const pp::Var&amp; var_message) {}
};
</pre>
<p>As in the example above, the Instance class for your module will likely include
an implementation of the <code>HandleMessage()</code> function. The browser calls an
instance&#8217;s <code>HandleMessage()</code> function every time the JavaScript code in an
application calls <code>postMessage()</code> to send a message to the instance. See the
<a class="reference internal" href="/native-client/devguide/coding/message-system.html"><em>Native Client messaging system</em></a> for more information about
how to send messages between JavaScript code and Native Client modules.</p>
<p>While the <code>CreateModule()</code> factory function, the <code>Module</code> class, and the
<code>Instance</code> class are required for a Native Client application, the code
samples shown above don&#8217;t actually do anything. Subsequent documents in the
Developer&#8217;s Guide build on these code samples and add more interesting
functionality.</p>
</section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,434 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="progress-events">
<span id="devcycle-progress-events"></span><h1 id="progress-events"><span id="devcycle-progress-events"></span>Progress Events</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#module-loading-and-progress-events" id="id3">Module loading and progress events</a></li>
<li><a class="reference internal" href="#handling-progress-events" id="id4">Handling progress events</a></li>
<li><a class="reference internal" href="#displaying-load-status" id="id5">Displaying load status</a></li>
<li><a class="reference internal" href="#the-lasterror-attribute" id="id6">The <code>lastError</code> attribute</a></li>
<li><a class="reference internal" href="#the-readystate-attribute" id="id7">The <code>readyState</code> attribute</a></li>
<li><a class="reference internal" href="#the-exitstatus-attribute" id="id8">The <code>exitStatus</code> attribute</a></li>
</ul>
</div>
<p>There are five types of events that developers can respond to in Native Client:
progress, message, view change, focus, and input events (each described in the
glossary below). This chapter describes how to monitor progress events (events
that occur during the loading and execution of a Native Client module). This
chapter assumes you are familiar with the material presented in the
<a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p>
<aside class="note">
The load_progress example illustrates progress event handling. You can find
this code in the <code>/examples/tutorial/load_progress/</code> directory in the Native
Client SDK download.
</aside>
<section id="module-loading-and-progress-events">
<h2 id="module-loading-and-progress-events">Module loading and progress events</h2>
<p>The Native Client runtime reports a set of state changes during the module
loading process by means of DOM progress events. This set of events is a direct
port of the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a> standard (except for the <code>crash</code>
event which is an extension of the W3C standard). The following table lists the
events types reported by the Native Client runtime:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Event</th>
<th class="head">Description</th>
<th class="head">Number of
times
triggered</th>
<th class="head">When event is
triggered</th>
<th class="head">How you might
react to
event</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><code>loadstart</code></td>
<td>Native Client has
started to load a
Native Client
module.</td>
<td>once</td>
<td>This is the
first
progress
event
triggered
after the
Native Client
module is
instantiated
and
initialized.</td>
<td>Display a
status
message, such
as
&#8220;Loading...&#8221;</td>
</tr>
<tr class="row-odd"><td><code>progress</code></td>
<td>Part of the module
has been loaded.</td>
<td>zero or
more</td>
<td>After
<code>loadstart</code>
has been
dispatched.</td>
<td>Display a
progress bar.</td>
</tr>
<tr class="row-even"><td><code>error</code></td>
<td>The Native Client
module failed to
start execution
(includes any
error before or
during
initialization of
the module). The
<code>lastError</code>
attribute
(mentioned later)
provides details
on the error
(initialization
failed, sel_ldr
did not start,
and so on).</td>
<td>zero or
once</td>
<td>After the
last
<code>progress</code>
event has
been
dispatched,
or after
<code>loadstart</code>
if no
<code>progress</code>
event was
dispatched.</td>
<td>Inform user
that the
application
failed to
load.</td>
</tr>
<tr class="row-odd"><td><code>abort</code></td>
<td>Loading of the
Native Client
module was
aborted by the
user.</td>
<td>zero or
once</td>
<td>After the
last
<code>progress</code>
event has
been
dispatched,
or after
<code>loadstart</code>
if no
<code>progress</code>
event was
dispatched.</td>
<td>It&#8217;s not
likely you
will want to
respond to
this event.</td>
</tr>
<tr class="row-even"><td><code>load</code></td>
<td>The Native Client
module was
successfully
loaded, and
execution was
started. (The
module was
initialized
successfully.)</td>
<td>zero or
once</td>
<td>After the
last
<code>progress</code>
event has
been
dispatched,
or after
<code>loadstart</code>
if no
<code>progress</code>
event was
dispatched.</td>
<td>Remove the
progress bar.</td>
</tr>
<tr class="row-odd"><td><code>loadend</code></td>
<td>Loading of the
Native Client
module has
stopped. Load
succeeded
(<code>load</code>),
failed
(<code>error</code>), or
was aborted
(<code>abort</code>).</td>
<td>once</td>
<td>After an
<code>error</code>,
<code>abort</code>, or
<code>load</code>
event was
dispatched.</td>
<td>Indicate
loading is
over
(regardless
of failure or
not).</td>
</tr>
<tr class="row-even"><td><code>crash</code></td>
<td>The Native Client
module is not
responding (died
on an
<code>assert()</code> or
<code>exit()</code>) after
a successful
load. This event
is unique to
Native Client and
is not part of
the W3C Progress
Events standard.
The <code>exitStatus</code>
attribute provides
the numeric exit
status value.</td>
<td>zero or
once</td>
<td>After a
<code>loadend</code>.</td>
<td>Notify user
that the
module did
something
illegal.</td>
</tr>
</tbody>
</table>
<p>The sequence of events for a successful module load is as follows:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Event is dispatched</th>
<th class="head">... then this task is attempted</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><code>loadstart</code></td>
<td>load the manifest file</td>
</tr>
<tr class="row-odd"><td><code>progress</code> (first time)</td>
<td>load the module</td>
</tr>
<tr class="row-even"><td><code>progress</code> (subsequent times)</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td><code>load</code></td>
<td>start executing the module</td>
</tr>
<tr class="row-even"><td><code>loadend</code></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<p>Errors that occur during loading are logged to the JavaScript console in Google
Chrome (select the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" /> &gt; Tools &gt; JavaScript console).</p>
</section><section id="handling-progress-events">
<h2 id="handling-progress-events">Handling progress events</h2>
<p>You should add event listeners in a <code>&lt;script&gt;</code> element to listen for these
events before the <code>&lt;embed&gt;</code> element is parsed. For example, the following code
adds a listener for the <code>load</code> event to a parent <code>&lt;div&gt;</code> element that also
contains the Native Client <code>&lt;embed&gt;</code> element. First, the listener is
attached. Then, when the listener <code>&lt;div&gt;</code> receives the <code>load</code> event, the
JavaScript <code>moduleDidLoad()</code> function is called. The following code is
excerpted from the example in <code>getting_started/part1/</code>:</p>
<pre class="prettyprint">
&lt;!--
Load the published pexe.
Note: Since this module does not use any real-estate in the browser, its
width and height are set to 0.
Note: The &lt;embed&gt; element is wrapped inside a &lt;div&gt;, which has both a 'load'
and a 'message' event listener attached. This wrapping method is used
instead of attaching the event listeners directly to the &lt;embed&gt; element to
ensure that the listeners are active before the NaCl module 'load' event
fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
pp::Instance.PostMessage() (in C++) from within the initialization code in
your module.
--&gt;
&lt;div id=&quot;listener&quot;&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var listener = document.getElementById('listener');
listener.addEventListener('load', moduleDidLoad, true);
listener.addEventListener('message', handleMessage, true);
&lt;/script&gt;
&lt;embed id=&quot;hello_tutorial&quot;
width=0 height=0
src=&quot;hello_tutorial.nmf&quot;
type=&quot;application/x-pnacl&quot; /&gt;
&lt;/div&gt;
</pre>
<p>Event listeners can be added to any DOM object. Since listeners set at the
outermost scope capture events for their contained elements, you can set
listeners on outer elements (including the <code>&lt;body&gt;</code> element) to handle events
from inner elements. For more information, see the W3 specifications for <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture">event
flow capture</a> and
<a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">event listener registration</a>.</p>
</section><section id="displaying-load-status">
<h2 id="displaying-load-status">Displaying load status</h2>
<p>One common response to progress events is to display the percentage of the
module that has been loaded. In the load_progress example, when the <code>progress</code>
event is triggered the <code>moduleLoadProgress</code> function is called. This function
uses the <code>lengthComputable</code>, <code>loaded</code>, and <code>total</code> attributes (described
in the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a>
standard) of the event to calculate the percentage of the module that has
loaded.</p>
<pre class="prettyprint">
function moduleLoadProgress(event) {
var loadPercent = 0.0;
var loadPercentString;
if (event.lengthComputable &amp;&amp; event.total &gt; 0) {
loadPercent = event.loaded / event.total * 100.0;
loadPercentString = loadPercent + '%';
common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
' (' + event.loaded + ' of ' + event.total + ' bytes)');
} else {
// The total length is not yet known.
common.logMessage('progress: Computing...');
}
}
</pre>
</section><section id="the-lasterror-attribute">
<h2 id="the-lasterror-attribute">The <code>lastError</code> attribute</h2>
<p>The <code>&lt;embed&gt;</code> element has a <code>lastError</code> attribute that is set to an
informative string whenever a load failure (an <code>error</code> or <code>abort</code> event)
occurs.</p>
<p>The following code adds an event listener before the <code>&lt;embed&gt;</code> element to
capture and handle an error in loading the Native Client module. The
<code>handleError()</code> function listens for an <code>error</code> event. When an error occurs,
this function prints the contents of the <code>lastError</code> attribute
(<code>embed_element.lastError</code>) as an alert.</p>
<pre class="prettyprint">
function domContentLoaded(name, tc, config, width, height) {
var listener = document.getElementById('listener');
...
listener.addEventListener('error', moduleLoadError, true);
...
common.createNaClModule(name, tc, config, width, height);
}
function moduleLoadError() {
common.logMessage('error: ' + common.naclModule.lastError);
}
</pre>
</section><section id="the-readystate-attribute">
<h2 id="the-readystate-attribute">The <code>readyState</code> attribute</h2>
<p>You can use the <code>readyState</code> attribute to monitor the loading process. This
attribute is particularly useful if you don&#8217;t care about the details of
individual progress events or when you want to poll for current load state
without registering listeners. The value of <code>readyState</code> progresses as follows
for a successful load:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Event</th>
<th class="head"><code>readyState</code> value</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>(before any events)</td>
<td><code>undefined</code></td>
</tr>
<tr class="row-odd"><td><code>loadstart</code></td>
<td>1</td>
</tr>
<tr class="row-even"><td><code>progress</code></td>
<td>3</td>
</tr>
<tr class="row-odd"><td><code>load</code></td>
<td>4</td>
</tr>
<tr class="row-even"><td><code>loadend</code></td>
<td>4</td>
</tr>
</tbody>
</table>
<p>The following code demonstrates how to monitor the loading process using the
<code>readyState</code> attribute. As before, the script that adds the event listeners
precedes the <code>&lt;embed&gt;</code> element so that the event listeners are in place before
the progress events are generated.</p>
<pre class="prettyprint">
&lt;html&gt;
...
&lt;body id=&quot;body&quot;&gt;
&lt;div id=&quot;status_div&quot;&gt;
&lt;/div&gt;
&lt;div id=&quot;listener_div&quot;&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var stat = document.getElementById('status_div');
function handleEvent(e) {
var embed_element = document.getElementById('my_embed');
stat.innerHTML +=
'&lt;br&gt;' + e.type + ': readyState = ' + embed_element.readyState;
}
var listener_element = document.getElementById('listener_div');
listener_element.addEventListener('loadstart', handleEvent, true);
listener_element.addEventListener('progress', handleEvent, true);
listener_element.addEventListener('load', handleEvent, true);
listener_element.addEventListener('loadend', handleEvent, true);
&lt;/script&gt;
&lt;embed
name=&quot;naclModule&quot;
id=&quot;my_embed&quot;
width=0 height=0
src=&quot;my_example.nmf&quot;
type=&quot;application/x-pnacl&quot; /&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</section><section id="the-exitstatus-attribute">
<h2 id="the-exitstatus-attribute">The <code>exitStatus</code> attribute</h2>
<p>This read-only attribute is set if the application calls <code>exit(n)</code>,
<code>abort()</code>, or crashes. Since NaCl modules are event handlers, there is no
need to call <code>exit(n)</code> in normal execution. If the module does exit or
crash, the <code>crash</code> progress event is issued and the <code>exitStatus</code> attribute
will contain the numeric value of the exit status:</p>
<ul class="small-gap">
<li>In the case of explicit calls to <code>exit(n)</code>, the numeric value will be
<code>n</code> (between 0 and 255).</li>
<li>In the case of crashes and calls to <code>abort()</code>, the numeric value will
be non-zero, but the exact value will depend on the chosen libc and the
target architecture, and may change in the future. Applications should not
rely on the <code>exitStatus</code> value being stable in these cases, but the value
may nevertheless be useful for temporary debugging.</li>
</ul>
</section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,232 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="url-loading">
<span id="devguide-coding-url-loading"></span><h1 id="url-loading"><span id="devguide-coding-url-loading"></span>URL Loading</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
<li><a class="reference internal" href="#reference-information" id="id2">Reference information</a></li>
<li><a class="reference internal" href="#background" id="id3">Background</a></li>
<li><p class="first"><a class="reference internal" href="#the-url-loader-example" id="id4">The <code>url_loader</code> example</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#url-loading-overview" id="id5">URL loading overview</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#url-loader-deep-dive" id="id6"><code>url_loader</code> deep dive</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#setting-up-the-request" id="id7">Setting up the request</a></li>
<li><a class="reference internal" href="#downloading-the-data" id="id8">Downloading the data</a></li>
<li><a class="reference internal" href="#displaying-a-result" id="id9">Displaying a result</a></li>
</ul>
</li>
</ul>
</div>
<section id="introduction">
<h2 id="introduction">Introduction</h2>
<p>This chapter describes how to use the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_u_r_l_loader">URLLoader API</a>
to load resources such as images and sound files from a server into your
application.</p>
<p>The example discussed in this chapter is included in the SDK in the directory
<code>examples/api/url_loader</code>.</p>
</section><section id="reference-information">
<h2 id="reference-information">Reference information</h2>
<p>For reference information related to loading data from URLs, see the
following documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/url__loader_8h">url_loader.h</a> -
Contains <code>URLLoader</code> class for loading data from URLs</li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/url__request__info_8h">url_request_info.h</a>
- Contains <code>URLRequest</code> class for creating and manipulating URL requests</li>
<li><a class="reference external" href="https://developers.google.com/native-client/peppercpp/url__response__info_8h">url_response_info.h</a>
- Contains <code>URLResponse</code> class for examaning URL responses</li>
</ul>
</section><section id="background">
<h2 id="background">Background</h2>
<p>When a user launches your Native Client web application, Chrome downloads and
caches your application&#8217;s HTML file, manifest file (.nmf), and Native Client
module (.pexe or .nexe). If your application needs additional assets, such as
images and sound files, it must explicitly load those assets. You can use the
Pepper APIs described in this chapter to load assets from a URL into your
application.</p>
<p>After you&#8217;ve loaded assets into your application, Chrome will cache those
assets. To avoid being at the whim of the Chrome cache, however, you may want
to use the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_file_i_o">Pepper FileIO API</a>
to write those assets to a persistent, sandboxed location on the user&#8217;s file
system.</p>
</section><section id="the-url-loader-example">
<h2 id="the-url-loader-example">The <code>url_loader</code> example</h2>
<p>The SDK includes an example called <code>url_loader</code> demonstrating downloading
files from a server. This example has these primary files:</p>
<ul class="small-gap">
<li><code>index.html</code> - The HTML code that launches the Native Client module.</li>
<li><code>example.js</code> - The JavaScript file for index.html. It has code that sends
a PostMessage request to the Native Client module when the &#8220;Get URL&#8221; button
is clicked.</li>
<li><code>url_loader_success.html</code> - An HTML file on the server whose contents are
being retrieved using the <code>URLLoader</code> API.</li>
<li><code>url_loader.cc</code> - The code that sets up and provides and entry point into
the Native client module.</li>
<li><code>url_loader_handler.cc</code> - The code that retrieves the contents of the
url_loader_success.html file and returns the results (this is where the
bulk of the work is done).</li>
</ul>
<p>The remainder of this document covers the code in the <code>url_loader.cc</code> and
<code>url_loader_handler.cc</code> files.</p>
<section id="url-loading-overview">
<h3 id="url-loading-overview">URL loading overview</h3>
<p>Like many Pepper APIs, the <code>URLLoader</code> API includes a set of methods that
execute asynchronously and that invoke callback functions in your Native Client
module. The high-level flow for the <code>url_loader</code> example is described below.
Note that methods in the namespace <code>pp::URLLoader</code> are part of the Pepper
<code>URLLoader</code> API, while the rest of the functions are part of the code in the
Native Client module (specifically in the file <code>url_loader_handler.cc</code>). The
following image shows the flow of the <code>url_loader_handler</code> code:</p>
<img alt="/native-client/images/pepper-urlloader-api.png" src="/native-client/images/pepper-urlloader-api.png" />
<p>Following are the high-level steps involved in URL loading.</p>
<ol class="arabic simple">
<li>The Native Client module calls <code>pp::URLLoader::Open</code> to begin opening the
URL.</li>
<li>When <code>Open</code> completes, it invokes a callback function in the Native Client
module (in this case, <code>OnOpen</code>).</li>
<li>The Native Client module calls the Pepper function
<code>URLLoader::ReadResponseBody</code> to begin reading the response body with the
data. <code>ReadResponseBody</code> is passed an optional callback function in the
Native Client module (in this case, On <code>Read</code>). The callback function is
an optional callback because <code>ReadResponseBody</code> may read data and return
synchronously if data is available (this improves performance for large
files and fast connections).</li>
</ol>
<p>The remainder of this document demonstrates how the previous steps are
implemented in the <code>url_loader</code> example.</p>
</section></section><section id="url-loader-deep-dive">
<h2 id="url-loader-deep-dive"><code>url_loader</code> deep dive</h2>
<section id="setting-up-the-request">
<h3 id="setting-up-the-request">Setting up the request</h3>
<p><code>HandleMessage</code> in <code>url_loader.cc</code> creates a <code>URLLoaderHandler</code> instance
and passes it the URL of the asset to be retrieved. Then <code>HandleMessage</code>
calls <code>Start</code> to start retrieving the asset from the server:</p>
<pre class="prettyprint">
void URLLoaderInstance::HandleMessage(const pp::Var&amp; var_message) {
if (!var_message.is_string()) {
return;
}
std::string message = var_message.AsString();
if (message.find(kLoadUrlMethodId) == 0) {
// The argument to getUrl is everything after the first ':'.
size_t sep_pos = message.find_first_of(kMessageArgumentSeparator);
if (sep_pos != std::string::npos) {
std::string url = message.substr(sep_pos + 1);
printf(&quot;URLLoaderInstance::HandleMessage('%s', '%s')\n&quot;,
message.c_str(),
url.c_str());
fflush(stdout);
URLLoaderHandler* handler = URLLoaderHandler::Create(this, url);
if (handler != NULL) {
// Starts asynchronous download. When download is finished or when an
// error occurs, |handler| posts the results back to the browser
// vis PostMessage and self-destroys.
handler-&gt;Start();
}
}
}
}
</pre>
<p>Notice that the constructor for <code>URLLoaderHandler</code> in
<code>url_loader_handler.cc</code> sets up the parameters of the URL request (using
<code>SetURL,</code> <code>SetMethod</code>, and <code>SetRecordDownloadProgress</code>):</p>
<pre class="prettyprint">
URLLoaderHandler::URLLoaderHandler(pp::Instance* instance,
const std::string&amp; url)
: instance_(instance),
url_(url),
url_request_(instance),
url_loader_(instance),
buffer_(new char[READ_BUFFER_SIZE]),
cc_factory_(this) {
url_request_.SetURL(url);
url_request_.SetMethod(&quot;GET&quot;);
url_request_.SetRecordDownloadProgress(true);
}
</pre>
</section><section id="downloading-the-data">
<h3 id="downloading-the-data">Downloading the data</h3>
<p><code>Start</code> in <code>url_loader_handler.cc</code> creates a callback (<code>cc</code>) using a
<code>CompletionCallbackFactory</code>. The callback is passed to <code>Open</code> to be called
upon its completion. <code>Open</code> begins loading the <code>URLRequestInfo</code>.</p>
<pre class="prettyprint">
void URLLoaderHandler::Start() {
pp::CompletionCallback cc =
cc_factory_.NewCallback(&amp;URLLoaderHandler::OnOpen);
url_loader_.Open(url_request_, cc);
}
</pre>
<p><code>OnOpen</code> ensures that the Open call was successful and, if so, calls
<code>GetDownloadProgress</code> to determine the amount of data to be downloaded so it
can allocate memory for the response body.</p>
<p>Note that the amount of data to be downloaded may be unknown, in which case
<code>GetDownloadProgress</code> sets <code>total_bytes_to_be_received</code> to -1. It is not a
problem if <code>total_bytes_to_be_received</code> is set to -1 or if
<code>GetDownloadProgress</code> fails; in these scenarios memory for the read buffer
can&#8217;t be allocated in advance and must be allocated as data is received.</p>
<p>Finally, <code>OnOpen</code> calls <code>ReadBody.</code></p>
<pre class="prettyprint">
void URLLoaderHandler::OnOpen(int32_t result) {
if (result != PP_OK) {
ReportResultAndDie(url_, &quot;pp::URLLoader::Open() failed&quot;, false);
return;
}
int64_t bytes_received = 0;
int64_t total_bytes_to_be_received = 0;
if (url_loader_.GetDownloadProgress(&amp;bytes_received,
&amp;total_bytes_to_be_received)) {
if (total_bytes_to_be_received &gt; 0) {
url_response_body_.reserve(total_bytes_to_be_received);
}
}
url_request_.SetRecordDownloadProgress(false);
ReadBody();
}
</pre>
<p><code>ReadBody</code> creates another <code>CompletionCallback</code> (a <code>NewOptionalCallback</code>)
and passes it to <code>ReadResponseBody,</code> which reads the response body, and
<code>AppendDataBytes,</code> which appends the resulting data to the previously read
data.</p>
<pre class="prettyprint">
void URLLoaderHandler::ReadBody() {
pp::CompletionCallback cc =
cc_factory_.NewOptionalCallback(&amp;URLLoaderHandler::OnRead);
int32_t result = PP_OK;
do {
result = url_loader_.ReadResponseBody(buffer_, READ_BUFFER_SIZE, cc);
if (result &gt; 0) {
AppendDataBytes(buffer_, result);
}
} while (result &gt; 0);
if (result != PP_OK_COMPLETIONPENDING) {
cc.Run(result);
}
}
void URLLoaderHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
if (num_bytes &lt;= 0)
return;
num_bytes = std::min(READ_BUFFER_SIZE, num_bytes);
url_response_body_.insert(
url_response_body_.end(), buffer, buffer + num_bytes);
}
</pre>
<p>Eventually either all the bytes have been read for the entire file (resulting
in <code>PP_OK</code> or 0), all the bytes have been read for what has been
downloaded, but more is to be downloaded (<code>PP_OK_COMPLETIONPENDING</code> or -1),
or there is an error (less than -1). <code>OnRead</code> is called in the event of an
error or <code>PP_OK</code>.</p>
</section><section id="displaying-a-result">
<h3 id="displaying-a-result">Displaying a result</h3>
<p>OnRead calls <code>ReportResultAndDie</code> when either an error or <code>PP_OK</code> is
returned to indicate streaming of file is complete. <code>ReportResultAndDie</code> then
calls <code>ReportResult,</code> which calls <code>PostMessage</code> to send the result back to
the HTML page.</p>
</section></section></section>
{{/partials.standard_nacl_article}}

@@ -0,0 +1,345 @@
{{+bindTo:partials.standard_nacl_article}}
<section id="view-change-focus-and-input-events">
<span id="view-focus-input-events"></span><h1 id="view-change-focus-and-input-events"><span id="view-focus-input-events"></span>View Change, Focus, and Input Events</h1>
<div class="contents local topic" id="contents">
<ul class="small-gap">
<li><a class="reference internal" href="#overview" id="id2">Overview</a></li>
<li><p class="first"><a class="reference internal" href="#handling-browser-events" id="id3">Handling browser events</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#didchangeview" id="id4">DidChangeView()</a></li>
<li><a class="reference internal" href="#didchangefocus" id="id5">DidChangeFocus()</a></li>
</ul>
</li>
<li><p class="first"><a class="reference internal" href="#handling-input-events" id="id6">Handling input events</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#registering-a-module-to-accept-input-events" id="id7">Registering a module to accept input events</a></li>
<li><a class="reference internal" href="#determining-and-branching-on-event-types" id="id8">Determining and branching on event types</a></li>
<li><a class="reference internal" href="#threading-and-blocking" id="id9">Threading and blocking</a></li>
</ul>
</li>
</ul>
</div>
<p>This chapter describes view change, focus, and input event handling for a
Native Client module. The chapter assumes you are familiar with the
material presented in the <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p>
<p>There are two examples used in this chapter to illustrate basic
programming techniques. The <code>input_events</code> example is used to
illustrate how your module can react to keyboard and mouse input
event. The <code>mouse_lock</code> example is used to illustrate how your module
can react to view change events. You can find these examples in the
<code>/examples/api/input_events</code> and <code>/examples/api/mouse_lock</code>
directories in the Native Client SDK. There is also the
ppapi_simple library that can be used to to implement most of the
boiler plate. The <code>pi_generator</code> example in
<code>/examples/demo/pi_generator</code> uses ppapi_simple to manage view
change events and 2D graphics.</p>
<section id="overview">
<h2 id="overview">Overview</h2>
<p>When a user interacts with the web page using a keyboard, mouse or
some other input device, the browser generates input events.
In a traditional web application, these input events are
passed to and handled in JavaScript, typically through event listeners
and event handlers. In a Native Client application, user interaction
with an instance of a module (e.g., clicking inside the rectangle
managed by a module) also generates input events, which are passed to
the module. The browser also passes view change and focus events that
affect a module&#8217;s instance to the module. Native Client modules can
override certain functions in the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_instance">pp::Instance</a>
class to handle input and browser events. These functions are listed in
the table below:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Function</th>
<th class="head">Event</th>
<th class="head">Use</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><code>DidChangeView</code></td>
<td>Called when the position,
size, or clip rectangle
of the module&#8217;s instance in
the browser has changed.
This event also occurs
when browser window is
resized or mouse wheel
is scrolled.</td>
<td>An implementation
of this function
might check the size
of the module
instance&#8217;s rectangle
has changed and
reallocate the
graphics context
when a different
size is received.</td>
</tr>
<tr class="row-odd"><td><code>DidChangeFocus</code></td>
<td>Called when the module&#8217;s
instance in the browser
has gone in or out of
focus (usually by
clicking inside or
outside the module
instance). Having focus
means that keyboard
events will be sent to
the module instance.
An instance&#8217;s default
condition is that it
does not have focus.</td>
<td>An implementation
of this function
might start or stop
an animation or a
blinking cursor.</td>
</tr>
<tr class="row-even"><td><code>HandleDocumentLoad</code></td>
<td>Called after
<code>pp::Instance::Init()</code>
for a full-frame module
instance that was
instantiated based on
the MIME type of a
DOMWindow navigation.
This situation only
applies to modules that
are pre-registered to
handle certain MIME
types. If you haven&#8217;t
specifically registered
to handle a MIME type or
aren&#8217;t positive this
applies to you, your
implementation of this
function can just return
false.</td>
<td>This API is only
applicable when you
are writing an
extension to enhance
the abilities of
the Chrome web
browser. For
example, a PDF
viewer might
implement this
function to download
and display a PDF
file.</td>
</tr>
<tr class="row-odd"><td><code>HandleInputEvent</code></td>
<td>Called when a user
interacts with the
module&#8217;s instance in the
browser using an input
device such as a mouse
or keyboard. You must
register your module to
accept input events
using
<code>RequestInputEvents()</code>
for mouse events and
<code>RequestFilteringInputEvents</code>
for keyboard events
prior to overriding this
function.</td>
<td>An implementation of
this function
examines the input
event type and
branches accordingly.</td>
</tr>
</tbody>
</table>
<p>These interfaces are found in the <a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_instance">pp::Instance class</a>.
The sections below provide examples of how to handle these events.</p>
</section><section id="handling-browser-events">
<h2 id="handling-browser-events">Handling browser events</h2>
<section id="didchangeview">
<h3 id="didchangeview">DidChangeView()</h3>
<p>In the <code>mouse_lock</code> example, <code>DidChangeView()</code> checks the previous size
of instance&#8217;s rectangle versus the new size. It also compares
other state such as whether or not the app is running in full screen mode.
If none of the state has actually changed, no action is needed.
However, if the size of the view or other state has changed, it frees the
old graphics context and allocates a new one.</p>
<pre class="prettyprint">
void MouseLockInstance::DidChangeView(const pp::View&amp; view) {
// DidChangeView can get called for many reasons, so we only want to
// rebuild the device context if we really need to.
if ((size_ == view.GetRect().size()) &amp;&amp;
(was_fullscreen_ == view.IsFullscreen()) &amp;&amp; is_context_bound_) {
return;
}
// ...
// Reallocate the graphics context.
size_ = view.GetRect().size();
device_context_ = pp::Graphics2D(this, size_, false);
waiting_for_flush_completion_ = false;
is_context_bound_ = BindGraphics(device_context_);
// ...
// Remember if we are fullscreen or not
was_fullscreen_ = view.IsFullscreen();
// ...
}
</pre>
<p>For more information about graphics contexts and how to manipulate images, see:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_image_data">pp::ImageData class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_graphics2_d">pp::Graphics2D class</a></li>
</ul>
</section><section id="didchangefocus">
<h3 id="didchangefocus">DidChangeFocus()</h3>
<p><code>DidChangeFocus()</code> is called when you click inside or outside of a
module&#8217;s instance in the web page. When the instance goes out
of focus (click outside of the instance), you might do something
like stop an animation. When the instance regains focus, you can
restart the animation.</p>
<pre class="prettyprint">
void DidChangeFocus(bool focus) {
// Do something like stopping animation or a blinking cursor in
// the instance.
}
</pre>
</section></section><section id="handling-input-events">
<h2 id="handling-input-events">Handling input events</h2>
<p>Input events are events that occur when the user interacts with a
module instance using the mouse, keyboard, or other input device
(e.g., touch screen). This section describes how the <code>input_events</code>
example handles input events.</p>
<section id="registering-a-module-to-accept-input-events">
<h3 id="registering-a-module-to-accept-input-events">Registering a module to accept input events</h3>
<p>Before your module can handle these events, you must register your
module to accept input events using <code>RequestInputEvents()</code> for mouse
events and <code>RequestFilteringInputEvents()</code> for keyboard events. For the
<code>input_events</code> example, this is done in the constructor of the
<code>InputEventInstance</code> class:</p>
<pre class="prettyprint">
class InputEventInstance : public pp::Instance {
public:
explicit InputEventInstance(PP_Instance instance)
: pp::Instance(instance), event_thread_(NULL), callback_factory_(this) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL |
PP_INPUTEVENT_CLASS_TOUCH);
RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
}
// ...
};
</pre>
<p><code>RequestInputEvents()</code> and <code>RequestFilteringInputEvents()</code> accept a
combination of flags that identify the class of events that the
instance is requesting to receive. Input event classes are defined in
the <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/group___enums.html#gafe68e3c1031daa4a6496845ff47649cd">PP_InputEvent_Class</a>
enumeration in <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/ppb__input__event_8h">ppb_input_event.h</a>.</p>
</section><section id="determining-and-branching-on-event-types">
<h3 id="determining-and-branching-on-event-types">Determining and branching on event types</h3>
<p>In a typical implementation, the <code>HandleInputEvent()</code> function
determines the type of each event using the <code>GetType()</code> function found
in the <code>InputEvent</code> class. The <code>HandleInputEvent()</code> function then uses a
switch statement to branch on the type of input event. Input events
are defined in the <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/group___enums.html#gaca7296cfec99fcb6646b7144d1d6a0c5">PP_InputEvent_Type</a>
enumeration in <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/ppb__input__event_8h">ppb_input_event.h</a>.</p>
<pre class="prettyprint">
virtual bool HandleInputEvent(const pp::InputEvent&amp; event) {
Event* event_ptr = NULL;
switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_UNDEFINED:
break;
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
case PP_INPUTEVENT_TYPE_MOUSEUP:
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
case PP_INPUTEVENT_TYPE_MOUSEENTER:
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
pp::MouseInputEvent mouse_event(event);
PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
switch (pp_button) {
case PP_INPUTEVENT_MOUSEBUTTON_NONE:
mouse_button = MouseEvent::kNone;
break;
case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
mouse_button = MouseEvent::kLeft;
break;
case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
mouse_button = MouseEvent::kMiddle;
break;
case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
mouse_button = MouseEvent::kRight;
break;
}
event_ptr =
new MouseEvent(ConvertEventModifier(mouse_event.GetModifiers()),
mouse_button,
mouse_event.GetPosition().x(),
mouse_event.GetPosition().y(),
mouse_event.GetClickCount(),
mouse_event.GetTimeStamp(),
event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
} break;
case PP_INPUTEVENT_TYPE_WHEEL: {
pp::WheelInputEvent wheel_event(event);
event_ptr =
new WheelEvent(ConvertEventModifier(wheel_event.GetModifiers()),
wheel_event.GetDelta().x(),
wheel_event.GetDelta().y(),
wheel_event.GetTicks().x(),
wheel_event.GetTicks().y(),
wheel_event.GetScrollByPage(),
wheel_event.GetTimeStamp());
} break;
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
case PP_INPUTEVENT_TYPE_KEYDOWN:
case PP_INPUTEVENT_TYPE_KEYUP:
case PP_INPUTEVENT_TYPE_CHAR: {
pp::KeyboardInputEvent key_event(event);
event_ptr = new KeyEvent(ConvertEventModifier(key_event.GetModifiers()),
key_event.GetKeyCode(),
key_event.GetTimeStamp(),
key_event.GetCharacterText().DebugString());
} break;
default: {
// For any unhandled events, send a message to the browser
// so that the user is aware of these and can investigate.
std::stringstream oss;
oss &lt;&lt; &quot;Default (unhandled) event, type=&quot; &lt;&lt; event.GetType();
PostMessage(oss.str());
} break;
}
event_queue_.Push(event_ptr);
return true;
}
</pre>
<p>Notice that the generic <code>InputEvent</code> received by <code>HandleInputEvent()</code> is
converted into a specific type after the event type is
determined. The event types handled in the example code are
<code>MouseInputEvent</code>, <code>WheelInputEvent</code>, and <code>KeyboardInputEvent</code>.
There are also <code>TouchInputEvents</code>. For the latest list of event types,
see the <a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_input_event">InputEvent documentation</a>.
For reference information related to the these event classes, see the
following documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_mouse_input_event">pp::MouseInputEvent class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_wheel_input_event">pp::WheelInputEvent class</a></li>
<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_keyboard_input_event">pp::KeyboardInputEvent class</a></li>
</ul>
</section><section id="threading-and-blocking">
<h3 id="threading-and-blocking">Threading and blocking</h3>
<p><code>HandleInputEvent()</code> in this example runs on the main module thread.
However, the bulk of the work happens on a separate worker thread (see
<code>ProcessEventOnWorkerThread</code>). <code>HandleInputEvent()</code> puts events in
the <code>event_queue_</code> and the worker thread takes events from the
<code>event_queue_</code>. This processing happens independently of the main
thread, so as not to slow down the browser.</p>
</section></section></section>
{{/partials.standard_nacl_article}}