From: SooChan Lim Date: Fri, 30 Mar 2018 11:08:55 +0000 (+0900) Subject: hwc: redesign the hwc X-Git-Tag: accepted/tizen/unified/20180416.213752~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F78%2F174378%2F16;p=platform%2Fcore%2Fuifw%2Flibtdm.git hwc: redesign the hwc change the frontend apis for hwc change the backend apis for hwc remove the useless codes Change-Id: I7571dfb817140ebc25a3bbff77dffb7edae2ff35 --- diff --git a/include/tdm.h b/include/tdm.h index 0f9bf5d..7beccd0 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -567,199 +567,14 @@ tdm_capture * tdm_output_create_capture(tdm_output *output, tdm_error *error); /** - * @brief Creates a new window on the given display. + * @brief Get a hwc associated with a output object. * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ -tdm_hwc_window * -tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); - -/** - * @brief Creates a new video window on the given output. - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ -tdm_hwc_window * -tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); - -/** - * @brief Destroys the given window. - * @param[in] output A output object - * @param[in] window the pointer of the window to destroy - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); - -/** - * @brief Set the client(relative to the TDM) target buffer - * @details Sets the buffer which will receive the output of client composition. - * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE - * will be composited into this buffer prior to the call to tdm_output_commit(), - * and windows not marked as TDM_COMPOSITION_CLIENT and - * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the - * device. - * - * The buffer handle provided may be null if no windows are being composited by - * the client. This must not result in an error (unless an invalid display - * handle is also provided). - * - * The damage parameter describes a buffer damage region as defined in the - * description of tdm_hwc_window_set_buffer_damage(). - * - * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) - * should be passed along with #target_buffer to allow tdm to make the smooth transition - * from a DEVICE type to a CLIENT type. - * - * Should be called before tdm_output_commit() if any of the layers are marked as - * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are - * so marked, then it is not necessary to call this function. It is not necessary - * to call tdm_output_hwc_validate() after changing the target through this function. - * @param[in] output A output object - * @param[in] target_buffer The new target buffer - * @param[in] damage The buffer damage region - * @param[in] composited_wnds The array of composited hwc_wnds - * @param[in] num_wnds The size of #composited_wnds array - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage); - -/** - * @brief Unset the client(relative to the TDM) target buffer - * @details TODO - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_unset_client_target_buffer(tdm_output *output); - -/** - * @brief Commit changes for a target_window - * @details After all change of a window object are applied, a user commit handler - * will be called. - * @param[in] hwc_window A window object - * @param[in] func A user commit handler - * @param[in] user_data The user data - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data); - -/** - * @brief Validate the output - * @details Instructs the device to inspect all of the layer state and - * determine if there are any composition type changes necessary before - * presenting the output. Permitted changes are described in the definition - * of tdm_hwc_window_composition_t above. - * @param[in] output A output object - * @param[out] num_types The number of composition type changes required by - * the device; if greater than 0, the client must either set and validate new - * types, or call tdm_output_hwc_accept_changes() to accept the changes returned by - * tdm_output_hwc_get_changed_composition_types(); must be the same as the number of - * changes returned by tdm_output_hwc_get_changed_composition_types (see the - * declaration of that function for more information); pointer will be non-NULL - * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A hwc object * @since 2.0.0 */ -tdm_error -tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, - uint32_t *num_types); - -/** - * @brief Set the 'need to validate' handler for the 'output' - * - * @details During backend's work it may need to ask for the revalidation - * (make client (E20) do tdm_output_hwc_validate() again), so a 'hndl' will - * be called as such need happen. Only one handler per output is supported. - * - * @param[in] output The output object a hndl is going to be registered for. - * @param[in] hndl The handler which will be called on the 'need to validate' event. - * - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_set_need_validate_handler(tdm_output *output, - tdm_output_need_validate_handler hndl); - -/** - * @brief Get changed composition types - * @details Retrieves the windows for which the device requires a different - * composition type than had been set prior to the last call to tdm_output_hwc_validate(). - * The client will either update its state with these types and call - * tdm_output_hwc_accept_changes, or will set new types and attempt to validate the - * display again. - * windows and types may be NULL to retrieve the number of elements which - * will be returned. The number of elements returned must be the same as the - * value returned in num_types from the last call to tdm_output_hwc_validate(). - * @param[in] output A output object - * @param[out] num_elements If windows or types were NULL, the number of layers - * and types which would have been returned; if both were non-NULL, the - * number of elements returned in layers and types, which must not exceed - * the value stored in num_elements prior to the call; pointer will be - * non-NULL - * @param[in] output A output object - * @param[out] windows An array of windows - * @param[out] composition_types An array of composition types, each corresponding - * to an element of windows - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_get_changed_composition_types(tdm_output *output,uint32_t *num_elements, - tdm_hwc_window **hwc_window, - tdm_hwc_window_composition *composition_types); - -/** - * @brief Accepts the changes required by the device - * @details Accepts the changes required by the device from the previous - * tdm_output_hwc_validate() call (which may be queried using - * tdm_output_get_chaged_composition_types()) and revalidates the display. This - * function is equivalent to requesting the changed types from - * tdm_output_get_chaged_composition_types(), setting those types on the - * corresponding windows, and then calling tdm_output_hwc_validate again. - * After this call it must be valid to present this display. Calling this after - * tdm_output_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but - * should have no other effect. - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_accept_changes(tdm_output *output); - -/** - * @brief Get a target buffer queue - * @details Buffers from target buffer queue will receive the output of - * client composition. Window marked as TDM_COMPOSITION_CLIENT or - * TDM_COMPOSITION_DEVICE_CANDIDATE will be composited into this buffers - * prior to the call to tdm_output_commit(). - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer queue - * @since 2.0.0 - */ -tbm_surface_queue_h -tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); - -/** - * @brief Get the supported format array for video hwc windows of a output object. - * @param[in] output A output object - * @param[out] formats The available format array - * @param[out] count The count of formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_output_hwc_get_video_supported_formats(tdm_layer *layer, const tbm_format **formats, - int *count); +tdm_hwc * +tdm_output_get_hwc(tdm_output *output, tdm_error *error); /** * @brief Get a output object of a layer object @@ -1000,6 +815,173 @@ tdm_error tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags); /** + * @brief Creates a new window on the given hwc. + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object + * @since 2.0.0 + */ +tdm_hwc_window * +tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error); + +/** + * @brief Get the supported format array for hwc windows of a hwc object. + * @param[in] hwc A output hwc + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count); + +/** + * @brief Get the available property array of a hwc object. + * @param[in] hwc A hwc + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count); + +/** + * @brief Get a target buffer queue + * @details Buffers from target buffer queue will receive the output of + * client composition. Window marked as TDM_COMPOSITION_CLIENT or + * TDM_COMPOSITION_DEVICE_CANDIDATE will be composited into this buffers + * prior to the call to tdm_output_commit(). + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A buffer queue + * @since 2.0.0 + */ +tbm_surface_queue_h +tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error); + +/** + * @brief Set the client(relative to the TDM) target buffer + * @details Sets the buffer which will receive the output of client composition. + * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE + * will be composited into this buffer prior to the call to tdm_output_commit(), + * and windows not marked as TDM_COMPOSITION_CLIENT and + * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the + * device. + * + * The buffer handle provided may be null if no windows are being composited by + * the client. This must not result in an error (unless an invalid display + * handle is also provided). + * + * The damage parameter describes a buffer damage region as defined in the + * description of tdm_hwc_window_set_buffer_damage(). + * + * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) + * should be passed along with #target_buffer to allow tdm to make the smooth transition + * from a DEVICE type to a CLIENT type. + * + * Should be called before tdm_output_commit() if any of the layers are marked as + * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are + * so marked, then it is not necessary to call this function. It is not necessary + * to call tdm_hwc_validate() after changing the target through this function. + * @param[in] hwc A output hwc + * @param[in] target_buffer The new target buffer + * @param[in] damage The buffer damage region + * @param[in] composited_wnds The array of composited hwc_wnds + * @param[in] num_wnds The size of #composited_wnds array + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_region damage); + +/** + * @brief Validate the output + * @details Instructs the device to inspect all of the layer state and + * determine if there are any composition type changes necessary before + * presenting the output. Permitted changes are described in the definition + * of tdm_hwc_window_composition_t above. + * @param[in] output A output object + * @param[out] num_types The number of composition type changes required by + * the device; if greater than 0, the client must either set and validate new + * types, or call tdm_hwc_accept_changes() to accept the changes returned by + * tdm_hwc_get_changed_composition_types(); must be the same as the number of + * changes returned by tdm_hwc_get_changed_composition_types (see the + * declaration of that function for more information); pointer will be non-NULL + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, + uint32_t *num_types); + +/** + * @brief Get changed composition types + * @details Retrieves the windows for which the device requires a different + * composition type than had been set prior to the last call to tdm_hwc_validate(). + * The client will either update its state with these types and call + * tdm_hwc_accept_changes, or will set new types and attempt to validate the + * display again. + * windows and types may be NULL to retrieve the number of elements which + * will be returned. The number of elements returned must be the same as the + * value returned in num_types from the last call to tdm_hwc_validate(). + * @param[in] output A output object + * @param[out] num_elements If windows or types were NULL, the number of layers + * and types which would have been returned; if both were non-NULL, the + * number of elements returned in layers and types, which must not exceed + * the value stored in num_elements prior to the call; pointer will be + * non-NULL + * @param[in] output A output object + * @param[out] windows An array of windows + * @param[out] composition_types An array of composition types, each corresponding + * to an element of windows + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types); + +/** + * @brief Accepts the changes required by the device + * @details Accepts the changes required by the device from the previous + * tdm_hwc_validate() call (which may be queried using + * tdm_hwc_get_chaged_composition_types()) and revalidates the display. This + * function is equivalent to requesting the changed types from + * tdm_hwc_get_chaged_composition_types(), setting those types on the + * corresponding windows, and then calling tdm_hwc_validate again. + * After this call it must be valid to present this display. Calling this after + * tdm_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but + * should have no other effect. + * @param[in] output A output object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_accept_changes(tdm_hwc *hwc); + +/** + * @brief Commit changes for a hwc + * @details After all change of a window object are applied, a user commit handler + * will be called. + * @param[in] hwc A hwc object + * @param[in] sync 0: asynchronous, 1:synchronous + * @param[in] func A user commit handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data); + +/** + * @brief Destroys the given window. + * @param[in] output A output object + * @param[in] window the pointer of the window to destroy + * @since 2.0.0 + */ +void +tdm_hwc_window_destroy(tdm_hwc_window *hwc_window); + +/** * @brief Get a buffer queue for the window object * @details These buffers are used to composite by hardware a client content in * the nocomp mode. @@ -1009,11 +991,11 @@ tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags); * @since 2.0.0 */ tbm_surface_queue_h -tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); +tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); /** * @brief Sets the desired composition type of the given window. - * @details During tdm_output_hwc_validate(), the device may request changes to + * @details During tdm_hwc_validate(), the device may request changes to * the composition types of any of the layers as described in the definition * of tdm_hwc_window_composition_t above. * @param[in] hwc_window A window object @@ -1047,7 +1029,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, * @since 2.0.0 */ tdm_error -tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage); +tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); /** * @brief Set the information to a window object @@ -1077,94 +1059,24 @@ tdm_error tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer); /** - * @brief Unset a TBM buffer to a window object - * @details A TBM buffer will be applied when the output object of a layer - * object is committed. - * @param[in] hwc_window A window object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @return #TDM_ERROR_BUSY if #hwc_window can't be updated right now, this - * can happen if #hwc_window is involved in the smooth transition from - * DEVICE to CLIENT, this shouldn't be interpreted like some critical error. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window); - -/** - * @brief Set a flags to a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); - -/** - * @brief Unset a flags from a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); - -/** - * @brief Commit changes for a window object - * @details After all change of a window object are applied, a user commit handler - * will be called. - * @param[in] hwc_window A window object - * @param[in] func A user commit handler - * @param[in] user_data The user data - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data); - -/** - * @brief Get the available property array of a video hwc window object. - * @param[in] hwc window A video hwc window object - * @param[out] props The available property array - * @param[out] count The count of properties - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count); - -/** * @brief Get the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[out] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error -tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, uint32_t id, - tdm_value *value); +tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, uint32_t id, tdm_value *value); /** * @brief Set the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[in] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error -tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, uint32_t id, - tdm_value value); - -/** - * @brief Get the window video capability - * @param[in] hwc_window A window object - * @param[out] video_capability A hwc window video capability - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); +tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, uint32_t id, tdm_value value); /** * @brief Destroy a pp object diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 0416a90..d43d73c 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -541,176 +541,12 @@ typedef struct _tdm_func_output { tdm_error (*output_set_dpms_async)(tdm_output *output, tdm_output_dpms dpms_value); /** - * @brief Creates a new window on the given display. + * @brief Get a hwc object of a output object * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ - tdm_hwc_window *(*output_hwc_create_window)(tdm_output *output, tdm_error *error); - - /** - * @brief Destroys the given window. - * @param[in] output A output object - * @param[in] window the pointer of the window to destroy - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_destroy_window)(tdm_output *output, tdm_hwc_window *hwc_window); - - /** - * @brief Set the client(relative to the TDM) target buffer - * @details Sets the buffer which will receive the output of client composition. - * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE - * will be composited into this buffer prior to the call to output_commit(), - * and windows not marked as TDM_COMPOSITION_CLIENT and - * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the - * device. - * - * The buffer handle provided may be null if no windows are being composited by - * the client. This must not result in an error (unless an invalid display - * handle is also provided). - * - * The damage parameter describes a buffer damage region as defined in the - * description of hwc_window_set_buffer_damage(). - * - * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) - * will be passed along with #target_buffer to allow tdm to make the smooth transition - * from a DEVICE type to a CLIENT type. - * - * Will be called before output_commit() if any of the layers are marked as - * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are - * so marked, then it is not necessary to call this function. It is not necessary - * to call output_hwc_validate() after changing the target through this function. - * @param[in] output A output object - * @param[in] target The new target buffer - * @param[in] damage The buffer damage region - * @param[in] composited_wnds The array of composited hwc_wnds - * @param[in] num_wnds The size of #composited_wnds array - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_set_client_target_buffer)(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage); - - /** - * @brief Unset the client(relative to the TDM) target buffer - * @details TODO - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_unset_client_target_buffer)(tdm_output *output); - - /** - * @brief Get the layer associated with the client target buffer - * @details TODO: - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer object. - * @since 2.0.0 - */ - tdm_layer *(*output_hwc_get_client_target_buffer_layer)(tdm_output *output, tdm_error *error); - - /** - * @brief Get the buffer which is set to the client target buffer - * @details TODO: - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer object. - * @since 2.0.0 - */ - tbm_surface_h (*output_hwc_get_client_target_buffer)(tdm_output *output, tdm_error *error); - - /** - * @brief Validate the output - * @details Instructs the device to inspect all of the layer state and - * determine if there are any composition type changes necessary before - * presenting the output. Permitted changes are described in the definition - * of tdm_composition_t above. - * @param[in] output A output object - * @param[out] num_types The number of composition type changes required by - * the device; if greater than 0, the client must either set and validate new - * types, or call output_hwc_accept_changes() to accept the changes returned by - * output_hwc_get_changed_composition_types(); must be the same as the number of - * changes returned by output_hwc_get_changed_composition_types (see the - * declaration of that function for more information); pointer will be non-NULL - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_validate)(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, - uint32_t *num_types); - - /** - * @brief Get changed composition types - * @details Retrieves the windows for which the device requires a different - * composition type than had been set prior to the last call to output_hwc_validate(). - * The client will either update its state with these types and call - * output_hwc_accept_changes, or will set new types and attempt to validate the - * display again. - * layers and types may be NULL to retrieve the number of elements which - * will be returned. The number of elements returned must be the same as the - * value returned in num_types from the last call to output_hwc_validate(). - * @param[in] output A output object - * @param[out] num_elements If windows or types were NULL, the number of layers - * and types which would have been returned; if both were non-NULL, the - * number of elements returned in layers and types, which must not exceed - * the value stored in num_elements prior to the call; pointer will be - * non-NULL - * @param[out] windows An array of windows - * @param[out] composition_types An array of composition types, each - * corresponding to an element of windows - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 + * @return A hwc object */ - tdm_error (*output_hwc_get_changed_composition_types)(tdm_output *output, - uint32_t *num_elements, - tdm_hwc_window **hwc_window, - tdm_hwc_window_composition *composition_types); - /** - * @brief Accepts the changes required by the device - * @details Accepts the changes required by the device from the previous - * output_hwc_validate() call (which may be queried using - * output_get_chaged_composition_types()) and revalidates the display. This - * function is equivalent to requesting the changed types from - * output_get_chaged_composition_types(), setting those types on the - * corresponding windows, and then calling output_hwc_validate again. - * After this call it must be valid to present this display. Calling this after - * output_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but - * should have no other effect. - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_accept_changes)(tdm_output *output); - - /** - * @brief Get a target buffer queue - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer queue - * @since 2.0.0 - */ - tbm_surface_queue_h (*output_hwc_get_target_buffer_queue)(tdm_output *output, - tdm_error *error); - - /** - * @brief Get the supported format array for video hwc windows of a output object. - * @param[in] output A output object - * @param[out] formats The available format array - * @param[out] count The count of formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*output_hwc_get_video_supported_formats)(tdm_layer *layer, - const tbm_format **formats, int *count); - - /** - * @brief Creates a new video window on the given output. - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object. If the video abilities isn't accessed return NULL - * @since 2.0.0 - */ - tdm_hwc_window *(*output_hwc_create_video_window)(tdm_output *output, tdm_error *error); + tdm_hwc *(*output_get_hwc)(tdm_output *output, tdm_error *error); void (*reserved5)(void); void (*reserved6)(void); @@ -847,23 +683,190 @@ typedef struct _tdm_func_layer { void (*reserved7)(void); } tdm_func_layer; +typedef struct _tdm_func_hwc { + /** + * @brief Create a new window on the given hwc. + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object + * @since 2.0.0 + */ + tdm_hwc_window *(*hwc_create_window)(tdm_hwc *hwc, tdm_error *error); + + /** + * @brief Get the supported format array for the hwc windows of a hwc object. + * @param[in] hwc A hwc object + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_get_supported_formats)(tdm_hwc *hwc, const tbm_format **formats, + int *count); + + + /** + * @brief Get the available property array of a hwc object. + * @param[in] hwc A hwc object + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_get_available_properties)(tdm_hwc *hwc, const tdm_prop **props, + int *count); + + /** + * @brief Get a target buffer queue + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A buffer queue + * @since 2.0.0 + */ + tbm_surface_queue_h (*hwc_get_client_target_buffer_queue)(tdm_hwc *hwc, + tdm_error *error); + + /** + * @brief Set the client(relative to the TDM) target buffer + * @details Sets the buffer which will receive the hwc of client composition. + * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE + * will be composited into this buffer prior to the call to hwc_commit(), + * and windows not marked as TDM_COMPOSITION_CLIENT and + * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the + * device. + * + * The buffer handle provided may be null if no windows are being composited by + * the client. This must not result in an error (unless an invalid display + * handle is also provided). + * + * The damage parameter describes a buffer damage region as defined in the + * description of hwc_window_set_buffer_damage(). + * + * Will be called before hwc_commit() if any of the layers are marked as + * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are + * so marked, then it is not necessary to call this function. It is not necessary + * to call hwc_validate() after changing the target through this function. + * @param[in] hwc A hwc object + * @param[in] target The new target buffer + * @param[in] damage The buffer damage region + * @param[in] composited_wnds The array of composited hwc_wnds + * @param[in] num_wnds The size of #composited_wnds array + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_set_client_target_buffer)(tdm_hwc *hwc, + tbm_surface_h target_buffer, + tdm_region damage); + + /** + * @brief Validate the hwc + * @details Instructs the device to inspect all of the layer state and + * determine if there are any composition type changes necessary before + * presenting the hwc. Permitted changes are described in the definition + * of tdm_composition_t above. + * @param[in] hwc A hwc object + * @param[out] num_types The number of composition type changes required by + * the device; if greater than 0, the client must either set and validate new + * types, or call hwc_accept_changes() to accept the changes returned by + * hwc_get_changed_composition_types(); must be the same as the number of + * changes returned by hwc_get_changed_composition_types (see the + * declaration of that function for more information); pointer will be non-NULL + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_validate)(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, + uint32_t num_wnds, uint32_t *num_types); + + /** + * @brief Get changed composition types + * @details Retrieves the windows for which the device requires a different + * composition type than had been set prior to the last call to hwc_validate(). + * The client will either update its state with these types and call + * hwc_accept_changes, or will set new types and attempt to validate the + * display again. + * layers and types may be NULL to retrieve the number of elements which + * will be returned. The number of elements returned must be the same as the + * value returned in num_types from the last call to hwc_validate(). + * @param[in] hwc A hwc object + * @param[out] num_elements If windows or types were NULL, the number of layers + * and types which would have been returned; if both were non-NULL, the + * number of elements returned in layers and types, which must not exceed + * the value stored in num_elements prior to the call; pointer will be + * non-NULL + * @param[out] windows An array of windows + * @param[out] composition_types An array of composition types, each + * corresponding to an element of windows + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_get_changed_composition_types)(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types); + /** + * @brief Accepts the changes required by the device + * @details Accepts the changes required by the device from the previous + * hwc_validate() call (which may be queried using + * hwc_get_chaged_composition_types()) and revalidates the display. This + * function is equivalent to requesting the changed types from + * hwc_get_chaged_composition_types(), setting those types on the + * corresponding windows, and then calling hwc_validate again. + * After this call it must be valid to present this display. Calling this after + * hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but + * should have no other effect. + * @param[in] hwc A hwc object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_accept_changes)(tdm_hwc *hwc); + + /** + * @brief Commit changes for a output object + * @param[in] hwc A hwc object + * @param[in] sync 0: asynchronous, 1:synchronous + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see hwc_set_commit_handler, tdm_hwc_commit_handler + * @remark + * When this function is called, a backend module @b SHOULD apply the all + * changes of the given output object to screen as well as the layer changes + * of this output. + * If this function returns TDM_ERROR_NONE, a backend module @b SHOULD call + * a user commit handler with the user data of this function after all + * changes of the given output object are applied. + */ + tdm_error (*hwc_commit)(tdm_hwc *hwc, int sync, void *user_data); + + /** + * @brief Set a user commit handler + * @param[in] hwc A hwc object + * @param[in] func A user commit handler + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_set_commit_handler)(tdm_output *hwc, tdm_hwc_commit_handler func); +} tdm_func_hwc; + /** * @brief The window functions for a backend module. * @since 2.0.0 */ -typedef struct _tdm_func_window { +typedef struct _tdm_func_hwc_window { + /** + * @brief Destroys the given window. + * @param[in] window the pointer of the window to destroy + * @since 2.0.0 + */ + void (*hwc_window_destroy)(tdm_hwc_window *hwc_window); + /** * @brief Get a buffer queue for the window object * @param[in] hwc_window A window object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. * @return A buffer queue */ - tbm_surface_queue_h (*hwc_window_get_tbm_buffer_queue)(tdm_hwc_window *hwc_window, - tdm_error *error); + tbm_surface_queue_h (*hwc_window_get_buffer_queue)(tdm_hwc_window *hwc_window, + tdm_error *error); /** * @brief Sets the desired composition type of the given window. - * @details During output_hwc_validate(), the device may request changes to + * @details During hwc_validate(), the device may request changes to * the composition types of any of the layers as described in the definition * of tdm_hwc_window_composition_t above. * @param[in] hwc_window A window object @@ -877,7 +880,7 @@ typedef struct _tdm_func_window { * @brief Set the buffer damage * @details Provides the region of the source buffer which has been modified * since the last frame. This region does not need to be validated before - * calling output_commit(). + * calling hwc_commit(). * Once set through this function, the damage region remains the same until a * subsequent call to this function. * If damage.num_rects > 0, then it may be assumed that any portion of the source @@ -894,11 +897,11 @@ typedef struct _tdm_func_window { * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error (*hwc_window_set_buffer_damage)(tdm_hwc_window *hwc_window, - tdm_hwc_region damage); + tdm_region damage); /** * @brief Set the information to a window object - * @details The information will be applied when the output object + * @details The information will be applied when the hwc object * of a layer object is committed. * @param[in] hwc_window A window object * @param[in] info The geometry information @@ -918,7 +921,7 @@ typedef struct _tdm_func_window { /** * @brief Set a TDM buffer to a window object - * @details A TDM buffer will be applied when the output object + * @details A TDM buffer will be applied when the hwc object * of a layer object is committed. * @param[in] hwc_window A window object * @param[in] buffer A TDM buffer @@ -932,104 +935,24 @@ typedef struct _tdm_func_window { tbm_surface_h buffer); /** - * @brief Unset a TDM buffer to a window object - * @details A TDM buffer will be applied when the output object - * of a layer object is committed. - * @param[in] hwc_window A window object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * - * Implementation should return #TDM_ERROR_BUSY if #hwc_window can't - * be updated right now, this won't be interpreted like some critical - * error. - */ - tdm_error (*hwc_window_unset_buffer)(tdm_hwc_window *hwc_window); - - /** - * @brief Get a buffer which is set to a window object - * @details A TDM buffer will be applied when the output object - * of a layer object is committed. - * @param[in] hwc_window A window object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer which is @b assigend to a window object - * - * Implementation should return #TDM_ERROR_BUSY if #hwc_window can't - * be updated right now, this won't be interpreted like some critical - * error. - */ - tbm_surface_h (*hwc_window_get_buffer)(tdm_hwc_window *hwc_window, - tdm_error *error); - - /** - * @brief Get a layer associated with a window object - * @param[in] hwc_window A window object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer which is @b assigend to a window object - * @remark - * A backend module @b SHOULD implement this function. The backend should - * return the tdm_layer assoicated with a hwc_window which must be assigend - * hw overlay.\n - */ - tdm_layer *(*hwc_window_get_layer)(tdm_hwc_window *hwc_window, - tdm_error *error); - - /** - * @brief Set a flags to a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_set_flags)(tdm_hwc_window *hwc_window, - tdm_hwc_window_flag flags); - - /** - * @brief Unset a flags from a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_unset_flags)(tdm_hwc_window *hwc_window, - tdm_hwc_window_flag flags); - - /** - * @brief Get the window video capability - * @param[in] hwc_window A window object - * @param[out] video_capability A hwc window video capability - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_video_get_capability)(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); - - /** - * @brief Get the available property array of a video hwc window object. - * @param[in] hwc window A video hwc window object - * @param[out] props The available property array - * @param[out] count The count of properties + * @brief Set the property which has a given id. + * @param[in] hwc window A hwc window object + * @param[in] id The property id + * @param[in] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ - tdm_error (*hwc_window_video_get_available_properties)( - tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count); + tdm_error (*hwc_window_set_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value value); /** * @brief Get the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[out] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ - tdm_error (*hwc_window_video_get_property)(tdm_hwc_window *hwc_window, - uint32_t id, tdm_value *value); - - /** - * @brief Set the property which has a given id. - * @param[in] hwc window A video hwc window object - * @param[in] id The property id - * @param[in] value The value - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_video_set_property)(tdm_hwc_window *hwc_window, - uint32_t id, tdm_value value); - + tdm_error (*hwc_window_get_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value *value); } tdm_func_hwc_window; /** @@ -1443,16 +1366,27 @@ tdm_event_loop_source_timer_update(tdm_event_loop_source *source, unsigned int m void tdm_event_loop_source_remove(tdm_event_loop_source *source); +/** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_string + */ +int +tdm_config_get_int(const char *key, int default_value); /** - * @brief Trigger a 'need to validate' event. - * @param[in] output The output the event should be triggered for. - * @note The global display lock has to be locked before the call to this function. - * @see #tdm_output_hwc_set_need_validate_handler - * @since 2.0.0 + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_int */ -tdm_error -tdm_backend_trigger_need_validate_event(tdm_output *output); +const char * +tdm_config_get_string(const char *key, const char *default_value); #ifdef __cplusplus } diff --git a/include/tdm_common.h b/include/tdm_common.h index ef5ee15..328f837 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -137,16 +137,6 @@ typedef enum { } tdm_layer_capability; /** - * @brief The hwc window capability enumeration - * @since 2.0.0 - */ -typedef enum { - TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCALE = (1 << 1), /**< if a hwc window video has scale capability */ - TDM_HWC_WINDOW_VIDEO_CAPABILITY_TRANSFORM = (1 << 2), /**< if a hwc window video has transform capability */ - TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCANOUT = (1 << 3), /**< if a hwc_window video allows a scanout buffer only */ -} tdm_hwc_window_video_capability; - -/** * @brief The pp capability enumeration * @details The scale, transform and CSC functionalities seem the default functions of PP. * If hardware device doesn't support one of them, we'd better let a developer know diff --git a/include/tdm_types.h b/include/tdm_types.h index 68f3096..32f544d 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -115,6 +115,15 @@ typedef struct _tdm_info_layer { } tdm_info_layer; /** + * @brief The region structure + * @since 2.0.0 + */ +typedef struct _tdm_region { + unsigned int num_rects; + tdm_pos const *rects; +} tdm_region; + +/** * @brief The hwc window info structure * @since 2.0.0 */ @@ -124,11 +133,6 @@ typedef struct _tdm_hwc_window_info { tdm_transform transform; } tdm_hwc_window_info; -typedef struct _tdm_hwc_region { - unsigned int num_rects; - tdm_pos const *rects; -} tdm_hwc_region; - /** * @brief The pp info structre */ @@ -173,18 +177,18 @@ typedef enum { */ TDM_COMPOSITION_CLIENT = 1, - /** Set by the client before tdm_output_hwc_validate(). + /** Set by the client before tdm_hwc_validate(). * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * TDM_COMPOSITION_DEVICE or TDM_COMPOSITION_CLIENT. */ TDM_COMPOSITION_DEVICE_CANDIDATE = 2, - /** Set by the HWC after tdm_output_hwc_validate(). + /** Set by the HWC after tdm_hwc_validate(). * * The device will handle the composition of this window through a hardware * overlay or other similar means. * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. */ TDM_COMPOSITION_DEVICE = 3, @@ -192,9 +196,9 @@ typedef enum { * asynchronously through layer_set_cursor_position. If this functionality is not * supported on a layer that the client sets to TDM_COMPOSITION_CURSOR, the * device must request that the composition type of that layer is changed to - * TDM_COMPOSITION_CLIENT upon the next call to tdm_output_hwc_validate(). + * TDM_COMPOSITION_CLIENT upon the next call to tdm_hwc_validate(). * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * either TDM_COMPOSITION_DEVICE or TDM_COMPOSITION_CLIENT. Changing to * TDM_COMPOSITION_DEVICE will prevent the use of layer_set_cursor_position but * still permit the device to composite the layer. */ @@ -236,7 +240,13 @@ typedef void tdm_output; typedef void tdm_layer; /** - * @brief The tdm window object + * @brief The tdm hwc object + * @since 2.0.0 + */ +typedef void tdm_hwc; + +/** + * @brief The tdm hwc window object * @since 2.0.0 */ typedef void tdm_hwc_window; @@ -290,20 +300,6 @@ typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence void *user_data); /** - * @brief The hwc_window commit handler - */ -typedef void (*tdm_hwc_window_commit_handler)(tdm_hwc_window *hwc_window, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - -/** - * @brief The output target_buffer commit handler - */ -typedef void (*tdm_output_hwc_target_buffer_commit_handler)(tdm_output *output, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - -/** * @brief The done handler of a pp object */ typedef void (*tdm_pp_done_handler)(tdm_pp *pp, tbm_surface_h src, @@ -321,10 +317,12 @@ typedef void (*tdm_capture_done_handler)(tdm_capture *capture, typedef void (*tdm_vblank_create_handler)(tdm_vblank *vblank, void *user_data); /** - * @brief The 'need to validate' handler of an output object - * @since 2.0.0 + * @brief The hwc commit handler + * @see hwc_set_commit_handler() function of #tdm_func_hwc */ -typedef void (*tdm_output_need_validate_handler)(tdm_output *output); +typedef void (*tdm_hwc_commit_handler)(tdm_hwc *hwc, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); #ifdef __cplusplus } diff --git a/src/Makefile.am b/src/Makefile.am index 7ec1cd4..f9616e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ libtdm_la_SOURCES = \ tdm_display.c \ tdm_output.c \ tdm_layer.c \ + tdm_hwc.c \ tdm_hwc_window.c \ tdm_pp.c \ tdm_capture.c \ diff --git a/src/tdm.c b/src/tdm.c index be3d0bf..bc59c3c 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -97,6 +97,44 @@ tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp return NULL; } +tdm_private_hwc * +tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_backend) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->hwc_backend == hwc_backend) + return private_hwc; + } + } + + return NULL; +} + +INTERN void * +tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->stamp == stamp) + return private_hwc; + } + } + + return NULL; +} + static void _tdm_display_destroy_caps_pp(tdm_caps_pp *caps_pp) { @@ -164,10 +202,12 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) { tdm_private_display *private_display = private_output->private_display; tdm_private_layer *l = NULL, *ll = NULL; + tdm_private_hwc *private_hwc = NULL; tdm_private_hwc_window *hw = NULL, *hww = NULL; tdm_private_capture *c = NULL, *cc = NULL; tdm_private_output_vblank_handler *v = NULL, *vv = NULL; tdm_private_output_commit_handler *om = NULL, *omm = NULL; + tdm_private_hwc_commit_handler *hm = NULL, *hmm = NULL; tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_output_change_handler *h = NULL, *hh = NULL; @@ -186,9 +226,17 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) free(om); } - LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { - LIST_DEL(&lm->link); - free(lm); + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hm, hmm, &private_hwc->hwc_commit_handler_list, link) { + LIST_DEL(&hm->link); + free(hm); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { + LIST_DEL(&lm->link); + free(lm); + } } LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) { @@ -218,21 +266,20 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) } LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_output->capture_list, link) - tdm_capture_destroy_internal(c); - - LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_output->hwc_window_list, link) - tdm_hwc_window_destroy_internal(hw); - - LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) - _tdm_display_destroy_private_layer(l); + tdm_capture_destroy_internal(c); + + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_hwc->hwc_window_list, link) + tdm_hwc_window_destroy_internal(hw); + free(private_hwc); + } else { + LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) + _tdm_display_destroy_private_layer(l); + } _tdm_display_destroy_caps_output(&private_output->caps); - tdm_thread_cb_remove(private_output, TDM_THREAD_CB_NEED_VALIDATE, NULL, - tdm_output_need_validate_handler_thread, NULL); - tdm_event_loop_source_remove(private_output->need_validate.event_source); - close(private_output->need_validate.event_fd); - /* when destroying output, vblank objects are also destroyed. vblank checks * if output object is valid. So delete the output's link at last. */ @@ -405,6 +452,8 @@ tdm_display_update_output(tdm_private_module *private_module, tdm_func_output *func_output = &private_module->func_output; tdm_private_output *private_output = NULL; tdm_layer **layers = NULL; + tdm_private_hwc *private_hwc = NULL; + tdm_hwc *hwc; int layer_count = 0, i; tdm_error ret; @@ -426,53 +475,82 @@ tdm_display_update_output(tdm_private_module *private_module, private_output->pipe = pipe; private_output->index = pipe; - LIST_INITHEAD(&private_output->layer_list); - LIST_INITHEAD(&private_output->hwc_window_list); LIST_INITHEAD(&private_output->capture_list); LIST_INITHEAD(&private_output->vblank_handler_list); LIST_INITHEAD(&private_output->output_commit_handler_list); - LIST_INITHEAD(&private_output->layer_commit_handler_list); LIST_INITHEAD(&private_output->pending_commit_handler_list); LIST_INITHEAD(&private_output->change_handler_list); - private_output->need_validate.event_fd = -1; - if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, tdm_output_cb_status, private_output); private_output->regist_change_cb = 1; } - } - - /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" - * because we have to get new modes. - */ - if (need_new_caps) { - _tdm_display_destroy_caps_output(&private_output->caps); ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) private_output->current_mode = NULL; - } - layers = func_output->output_get_layers(output_backend, &layer_count, &ret); - if (ret != TDM_ERROR_NONE) { - free(layers); - return ret; + /* get the tdm_hwc object */ + if (private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) { + hwc = func_output->output_get_hwc(output_backend, &ret); + TDM_RETURN_VAL_IF_FAIL(hwc != NULL, ret); + + private_hwc = calloc(1, sizeof(tdm_private_hwc)); + TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_OUT_OF_MEMORY); + + private_hwc->private_module = private_module; + private_hwc->private_output = private_output; + private_hwc->hwc_backend = hwc; + private_hwc->index = pipe; + private_hwc->stamp = tdm_helper_get_time(); + while (tdm_display_find_hwc_stamp(private_module->private_display, private_hwc->stamp)) + private_hwc->stamp++; + + LIST_INITHEAD(&private_hwc->hwc_window_list); + LIST_INITHEAD(&private_hwc->hwc_commit_handler_list); + + private_output->private_hwc = private_hwc; + } else { + LIST_INITHEAD(&private_output->layer_list); + LIST_INITHEAD(&private_output->layer_commit_handler_list); + } + } else { + /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" + * because we have to get new modes. + */ + if (need_new_caps) { + _tdm_display_destroy_caps_output(&private_output->caps); + + ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + private_output->current_mode = NULL; + } } - for (i = 0; i < layer_count; i++) { - ret = _tdm_display_update_layer(private_output, layers[i], i); + /* do not use the layer object when the tdm_output has the hwc capability */ + if ((private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) == 0) { + layers = func_output->output_get_layers(output_backend, &layer_count, &ret); if (ret != TDM_ERROR_NONE) { free(layers); return ret; } - } - free(layers); + for (i = 0; i < layer_count; i++) { + ret = _tdm_display_update_layer(private_output, layers[i], i); + if (ret != TDM_ERROR_NONE) { + free(layers); + return ret; + } + } + + free(layers); + } return TDM_ERROR_NONE; } @@ -1005,6 +1083,10 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_load; + ret = tdm_hwc_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_load; + ret = tdm_pp_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; @@ -1054,15 +1136,6 @@ tdm_display_init(tdm_error *error) private_display->init_count = 1; g_private_display = private_display; - tdm_private_module *b = NULL; - tdm_private_output *o = NULL; - LIST_FOR_EACH_ENTRY(b, &private_display->module_list, link) { - LIST_FOR_EACH_ENTRY(o, &b->output_list, link) { - if (o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - tdm_output_need_validate_event_init(o); - } - } - /* the COMMIT_PER_VBLANK functionality is ability of an output to support * several operational modes (commit_per_vblank modes) related to tdm_commit; * this functionality can be turned off which means a default mode */ diff --git a/src/tdm_backend.c b/src/tdm_backend.c index 8be51f0..13ea24c 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -133,6 +133,31 @@ tdm_backend_register_func_layer(tdm_display *dpy, tdm_func_layer *func_layer) /* LCOV_EXCL_START */ EXTERN tdm_error +tdm_backend_register_func_hwc(tdm_display *dpy, tdm_func_hwc *func_hwc) +{ + tdm_backend_module *module; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); + + BACKEND_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(func_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); + + assert(private_display->current_module); + + module = private_display->current_module->module_data; + /* FIX ME: + Temporarily, we set the version of hwc window to 1.1 for the development. + Originally the hwc window version is 2.0. */ + if (_check_abi_version(module, 1, 1) < 0) + return TDM_ERROR_BAD_MODULE; + + private_display->current_module->func_hwc = *func_hwc; + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func_hwc_window) { tdm_backend_module *module; @@ -205,49 +230,3 @@ tdm_backend_register_func_capture(tdm_display *dpy, return TDM_ERROR_NONE; } - -/* LCOV_EXCL_START */ -/* backend operates itself types */ -static tdm_private_output* -_look_for_frontend_hwc_output(tdm_output *backend_output) -{ - tdm_private_output *frontend_output = NULL, *o = NULL; - tdm_private_display *private_display = tdm_display_get(); - tdm_private_module *private_module = NULL; - - LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { - LIST_FOR_EACH_ENTRY(o, &private_module->output_list, link) { - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - continue; - - if (o->output_backend == backend_output) { - frontend_output = o; - return frontend_output; - } - } - } - - return NULL; -} - -EXTERN tdm_error -tdm_backend_trigger_need_validate_event(tdm_output *output) -{ - tdm_private_output *private_output; - uint64_t value; - int res; - - private_output = _look_for_frontend_hwc_output(output); - TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); - - value = 1; - - /* do not lock the global display lock here */ - - res = write(private_output->need_validate.event_fd, &value, sizeof(value)); - if (res < 0) - return TDM_ERROR_OPERATION_FAILED; - - return TDM_ERROR_NONE; -} -/* LCOV_EXCL_STOP */ diff --git a/src/tdm_hwc.c b/src/tdm_hwc.c new file mode 100644 index 0000000..115197c --- /dev/null +++ b/src/tdm_hwc.c @@ -0,0 +1,550 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: SooChan Lim , + * Boram Park , + * Changyeon Lee , + * Sangjin Lee + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tdm_private.h" + +#define HWC_FUNC_ENTRY() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_display = private_output->private_display + +#define HWC_FUNC_ENTRY_ERROR() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_display = private_output->private_display + +#define HWC_FUNC_ENTRY_VOID_RETURN() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_IF_FAIL(hwc != NULL); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_IF_FAIL(private_output != NULL); \ + private_display = private_output->private_display + + +static tdm_private_hwc_window * +_tdm_hwc_find_private_hwc_window(tdm_private_hwc *private_hwc, tdm_hwc_window *hwc_window_backend) +{ + tdm_private_hwc_window *private_hwc_window = NULL; + + LIST_FOR_EACH_ENTRY(private_hwc_window, &private_hwc->hwc_window_list, link) { + if (private_hwc_window->hwc_window_backend == hwc_window_backend) + return private_hwc_window; + } + + return NULL; +} + +static void +_tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object, + tdm_thread_cb_base *cb_base, void *user_data) +{ + tdm_thread_cb_hwc_commit *hwc_commit = (tdm_thread_cb_hwc_commit *)cb_base; + tdm_private_hwc_commit_handler *hwc_commit_handler = hwc_commit->base.data; + tdm_private_hwc *private_hwc = object; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + if (!hwc_commit_handler) + return; + + assert(hwc_commit_handler->owner_tid == syscall(SYS_gettid)); + + tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + + LIST_DEL(&hwc_commit_handler->link); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) { + TDM_INFO("----------------------------------------- hwc(%d) committed", private_hwc->index); + TDM_INFO("handler(%p)", hwc_commit_handler); + } + + if (hwc_commit_handler->func) { + _pthread_mutex_unlock(&private_display->lock); + hwc_commit_handler->func(private_hwc, + hwc_commit->sequence, + hwc_commit->tv_sec, + hwc_commit->tv_usec, + hwc_commit_handler->user_data); + _pthread_mutex_lock(&private_display->lock); + } + + free(hwc_commit_handler); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("-----------------------------------------..."); +} + +static void +_tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_hwc_commit_handler *hwc_commit_handler = user_data; + tdm_private_hwc *private_hwc; + tdm_thread_cb_hwc_commit hwc_commit; + tdm_error ret; + + if (hwc_commit_handler) + private_hwc = hwc_commit_handler->private_hwc; + else + private_hwc = tdm_display_find_private_hwc(tdm_display_get(), hwc_backend); + + memset(&hwc_commit, 0, sizeof hwc_commit); + hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT; + hwc_commit.base.length = sizeof hwc_commit; + hwc_commit.base.object_stamp = private_hwc->stamp; + hwc_commit.base.data = hwc_commit_handler; + hwc_commit.base.sync = 0; + hwc_commit.sequence = sequence; + hwc_commit.tv_sec = tv_sec; + hwc_commit.tv_usec = tv_usec; + + ret = tdm_thread_cb_call(private_hwc, &hwc_commit.base, 1); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +INTERN tdm_error +tdm_hwc_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_HWC_COMMIT, tdm_display_find_hwc_stamp); + + return TDM_ERROR_NONE; +} + +EXTERN tdm_hwc_window * +tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error) +{ + tdm_hwc_window *hwc_window = NULL; + + HWC_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_hwc, error); + + _pthread_mutex_unlock(&private_display->lock); + + return hwc_window; +} + +EXTERN tdm_error +tdm_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_supported_formats) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_supported_formats(private_hwc->hwc_backend, formats, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_available_properties) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_available_properties(private_hwc->hwc_backend, props, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tbm_surface_queue_h +tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tbm_surface_queue_h queue = NULL; + + HWC_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_client_target_buffer_queue) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return NULL; + /* LCOV_EXCL_STOP */ + } + + queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error); + + _pthread_mutex_unlock(&private_display->lock); + + return queue; +} + +EXTERN tdm_error +tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_region damage) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) { + /* LCOV_EXCL_START */ + char str[TDM_PATH_LEN]; + static int i; + snprintf(str, TDM_PATH_LEN, "target_window_%03d", i++); + tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str); + /* LCOV_EXCL_STOP */ + } + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_set_client_target_buffer) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + + +EXTERN tdm_error +tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_window **composited_wnds_frontend = NULL; + tdm_hwc_window **composited_wnds_backend = NULL; + int i; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_validate) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + if (num_wnds == 0) { + ret = func_hwc->hwc_validate(private_hwc->hwc_backend, NULL, 0, num_types); + + _pthread_mutex_unlock(&private_display->lock); + return ret; + } + + composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *)); + if (!composited_wnds_backend) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds; + + for (i = 0; i < num_wnds; i++) + composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend; + + ret = func_hwc->hwc_validate(private_hwc->hwc_backend, composited_wnds_backend, + num_wnds, num_types); + + free(composited_wnds_backend); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_window * private_hwc_window = NULL; + int i = 0; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_changed_composition_types) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_changed_composition_types(private_hwc->hwc_backend, + num_elements, hwc_window, composition_types); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + return ret; + /* LCOV_EXCL_STOP */ + } + + if (hwc_window == NULL || composition_types == NULL) { + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + for (i = 0; i < *num_elements; i++) { + private_hwc_window = _tdm_hwc_find_private_hwc_window(private_hwc, hwc_window[i]); + if (private_hwc_window == NULL) { + /* LCOV_EXCL_START */ + TDM_ERR("failed! This should never happen!"); + tdm_hwc_window_destroy_internal(private_hwc_window); + *num_elements = 0; + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + + hwc_window[i] = (tdm_hwc_window*)private_hwc_window; + } + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_accept_changes(tdm_hwc *hwc) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_validate) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_accept_changes(private_hwc->hwc_backend); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_commit_handler *hwc_commit_handler = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_commit) { + /* LCOV_EXCL_START */ + TDM_WRN("not implemented!!"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + +//TODO: I am not sure yet whether we have to check the dpms at hwc_commit. +#if 0 + /* check if the dpms is off */ + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { + TDM_ERR("hwc(%d) dpms: %s", private_hwc->index, + tdm_dpms_str(private_output->current_dpms_value)); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_DPMS_OFF; + } +#endif + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) commit", private_hwc->index); + + if (!private_hwc->regist_commit_cb) { + private_hwc->regist_commit_cb = 1; + ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit); + /* LCOV_EXCL_START */ + if (ret != TDM_ERROR_NONE) { + private_hwc->regist_commit_cb = 0; + TDM_ERR("hwc(%d) fail to set hwc_set_commit_handler", private_hwc->index); + _pthread_mutex_unlock(&private_display->lock); + return ret; + /* LCOV_EXCL_STOP */ + } + } + + hwc_commit_handler = calloc(1, sizeof(tdm_private_hwc_commit_handler)); + if (!hwc_commit_handler) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + ret = tdm_thread_cb_add(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(hwc_commit_handler); + return ret; + } + + LIST_ADDTAIL(&hwc_commit_handler->link, &private_hwc->hwc_commit_handler_list); + hwc_commit_handler->private_hwc = private_hwc; + hwc_commit_handler->func = func; + hwc_commit_handler->user_data = user_data; + hwc_commit_handler->owner_tid = syscall(SYS_gettid); + + ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)", + private_hwc->index, hwc_commit_handler, func, user_data); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; + +commit_failed: + /* LCOV_EXCL_START */ + if (hwc_commit_handler) { + tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + LIST_DEL(&hwc_commit_handler->link); + free(hwc_commit_handler); + } + + _pthread_mutex_unlock(&private_display->lock); + + return ret; + /* LCOV_EXCL_STOP */ +} \ No newline at end of file diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 25692b3..78df88d 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -2,14 +2,12 @@ * * libtdm * - * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved. * - * Contact: Eunchul Kim , - * JinYoung Jeon , - * Taeheon Kim , - * YoungJun Cho , - * SooChan Lim , - * Boram Park + * Contact: SooChan Lim , + * Boram Park , + * Changyeon Lee , + * Sangjin Lee * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -46,35 +44,148 @@ #define HWC_WINDOW_FUNC_ENTRY() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_display = private_output->private_display #define HWC_WINDOW_FUNC_ENTRY_ERROR() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ private_display = private_output->private_display #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_IF_FAIL(hwc_window != NULL); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_IF_FAIL(private_hwc != NULL); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_IF_FAIL(private_output != NULL); \ private_display = private_output->private_display -tbm_surface_queue_h -tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) + +INTERN tdm_hwc_window * +tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error) +{ + tdm_private_output *private_output = private_hwc->private_output; + tdm_private_module *private_module = private_output->private_module; + tdm_func_hwc *func_hwc = &private_module->func_hwc; + tdm_private_hwc_window *private_hwc_window = NULL; + tdm_hwc_window *hwc_window_backend = NULL; + tdm_error ret = TDM_ERROR_NONE; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); + + if (!func_hwc->hwc_create_window) { + /* LCOV_EXCL_START */ + if (error) + *error = TDM_ERROR_BAD_MODULE; + return NULL; + /* LCOV_EXCL_STOP */ + } + + private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window)); + if (!private_hwc_window) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + /* LCOV_EXCL_STOP */ + } + + hwc_window_backend = func_hwc->hwc_create_window(private_hwc->hwc_backend, &ret); + if (ret != TDM_ERROR_NONE) { + free(private_hwc_window); + if (error) + *error = ret; + return NULL; + } + + LIST_ADD(&private_hwc_window->link, &private_hwc->hwc_window_list); + + private_hwc_window->private_hwc = private_hwc; + private_hwc_window->hwc_window_backend = hwc_window_backend; + + TDM_DBG("hwc_window(%p) create", private_hwc_window); + + if (error) + *error = TDM_ERROR_NONE; + + return private_hwc_window; +} + +INTERN void +tdm_hwc_window_destroy_internal(tdm_private_hwc_window *private_hwc_window) +{ + tdm_private_output *private_output; + tdm_private_module *private_module; + tdm_private_hwc *private_hwc; + tdm_func_hwc_window *func_hwc_window; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + if (!private_hwc_window) + return; + + private_hwc = private_hwc_window->private_hwc; + private_output = private_hwc->private_output; + private_module = private_output->private_module; + func_hwc_window = &private_module->func_hwc_window; + + LIST_DEL(&private_hwc_window->link); + + func_hwc_window = &private_module->func_hwc_window; + func_hwc_window->hwc_window_destroy(private_hwc_window->hwc_window_backend); + + free(private_hwc_window); +} + +EXTERN void +tdm_hwc_window_destroy(tdm_hwc_window *hwc_window) +{ + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_hwc *private_hwc; + tdm_private_hwc_window *private_hwc_window; + + if (!hwc_window) + return; + + private_hwc_window = (tdm_private_hwc_window *)hwc_window; + private_hwc = private_hwc_window->private_hwc; + private_output = private_hwc->private_output; + private_display = private_output->private_display; + + _pthread_mutex_lock(&private_display->lock); + + tdm_hwc_window_destroy_internal(hwc_window); + + _pthread_mutex_unlock(&private_display->lock); +} + +EXTERN tbm_surface_queue_h +tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -87,7 +198,8 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) { + if (!func_hwc_window->hwc_window_get_buffer_queue) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); if (error) @@ -95,7 +207,7 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error return NULL; } - queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error); + queue = func_hwc_window->hwc_window_get_buffer_queue(private_hwc_window->hwc_window_backend, error); _pthread_mutex_unlock(&private_display->lock); @@ -132,7 +244,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, } EXTERN tdm_error -tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage) +tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -237,339 +349,7 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) } EXTERN tdm_error -tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_unset_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_unset_buffer(private_hwc_window->hwc_window_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -INTERN tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, - tdm_error *error) -{ - tdm_private_display *private_display = private_output->private_display; - tdm_private_module *private_module = private_output->private_module; - tdm_func_output *func_output = &private_module->func_output; - tdm_private_hwc_window *private_hwc_window = NULL; - tdm_hwc_window *hwc_window_backend = NULL; - tdm_error ret = TDM_ERROR_NONE; - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - - if (!is_video) { - if (!func_output->output_hwc_create_window) { - if (error) - *error = TDM_ERROR_BAD_MODULE; - return NULL; - } - - hwc_window_backend = func_output->output_hwc_create_window( - private_output->output_backend, &ret); - if (ret != TDM_ERROR_NONE) { - if (error) - *error = ret; - return NULL; - } - } else { - if (!func_output->output_hwc_create_video_window) { - if (error) - *error = TDM_ERROR_NOT_IMPLEMENTED; - return NULL; - } - - hwc_window_backend = func_output->output_hwc_create_video_window( - private_output->output_backend, &ret); - if (ret != TDM_ERROR_NONE) { - if (error) - *error = ret; - return NULL; - } - } - - private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window)); - if (!private_hwc_window) { - TDM_ERR("failed: alloc memory"); - func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend); - if (error) - *error = TDM_ERROR_OUT_OF_MEMORY; - return NULL; - } - - LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list); - - private_hwc_window->private_display = private_display; - private_hwc_window->private_output = private_output; - private_hwc_window->hwc_window_backend = hwc_window_backend; - - TDM_DBG("hwc_window(%p) create", private_hwc_window); - - if (error) - *error = TDM_ERROR_NONE; - - return private_hwc_window; -} - -INTERN tdm_error -tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window) -{ - tdm_private_output *private_output; - tdm_private_module *private_module; - tdm_func_output *func_output; - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); - - if (!private_hwc_window) - return TDM_ERROR_OPERATION_FAILED; - - private_output = private_hwc_window->private_output; - private_module = private_output->private_module; - - LIST_DEL(&private_hwc_window->link); - - func_output = &private_module->func_output; - func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend); - - free(private_hwc_window); - return TDM_ERROR_NONE; -} - -EXTERN tdm_error -tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_set_flags) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_unset_flags) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static void -_tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data; - tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func; - tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window; - void *data = hwc_window_commit_handler->user_data; - - func(hwc_window, sequence, tv_sec, tv_usec, data); - - free(hwc_window_commit_handler); -} - -tdm_error -tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - tdm_private_hwc_window_commit_handler *hwc_window_commit_handler; - tdm_layer *layer = NULL; - tdm_private_layer *private_layer; - tdm_info_layer *info_layer; - tdm_hwc_window_info window_info; - tbm_surface_h buffer; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_get_layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend, - &ret); - if (!layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("no assigned layer!!"); - return TDM_ERROR_INVALID_PARAMETER; - } - - private_layer = (tdm_private_layer*)layer; - - buffer = func_hwc_window->hwc_window_get_buffer(private_hwc_window->hwc_window_backend, - &ret); - if (buffer) - ret = tdm_layer_set_buffer_internal(private_layer, buffer); - else - ret = tdm_layer_unset_buffer_internal(private_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set buffer(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend, - &window_info); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - info_layer = (tdm_info_layer *)&window_info; - ret = tdm_layer_set_info_internal(private_layer, info_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler)); - if (!hwc_window_commit_handler) { - TDM_ERR("failed: alloc memory"); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - hwc_window_commit_handler->private_hwc_window = private_hwc_window; - hwc_window_commit_handler->func = func; - hwc_window_commit_handler->user_data = user_data; - - ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, hwc_window_commit_handler); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(window)"); - free(hwc_window_commit_handler); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_video_get_capability) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend, - video_capability); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_video_get_available_properties) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend, - props, count); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, - unsigned int id, tdm_value *value) +tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -583,14 +363,14 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_video_get_property) { + if (!func_hwc_window->hwc_window_get_property) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; } - ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend, - id, value); + ret = func_hwc_window->hwc_window_get_property(private_hwc_window->hwc_window_backend, id, value); _pthread_mutex_unlock(&private_display->lock); @@ -598,8 +378,7 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, } EXTERN tdm_error -tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, - unsigned int id, tdm_value value) +tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -611,14 +390,14 @@ tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_video_set_property) { + if (!func_hwc_window->hwc_window_set_property) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; } - ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend, - id, value); + ret = func_hwc_window->hwc_window_set_property(private_hwc_window->hwc_window_backend, id, value); _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_macro.h b/src/tdm_macro.h index a84b82a..5b8f861 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -253,7 +253,7 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, { TDM_THREAD_CB_VBLANK_CREATE, "vblank-create" }, - { TDM_THREAD_CB_NEED_VALIDATE, "need-validate" }, + { TDM_THREAD_CB_HWC_COMMIT, "hwc-commit" }, }; TDM_TYPE_NAME_FN(cb_type) diff --git a/src/tdm_output.c b/src/tdm_output.c index 9b9d200..ee760c1 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -127,20 +127,6 @@ _tdm_output_vblank_timeout_update(tdm_private_output *private_output, int ms_del } } -static tdm_private_hwc_window * -_tdm_output_find_private_hwc_window(tdm_private_output *private_output, - tdm_hwc_window *hwc_window_backend) -{ - tdm_private_hwc_window *private_hwc_window = NULL; - - LIST_FOR_EACH_ENTRY(private_hwc_window, &private_output->hwc_window_list, link) { - if (private_hwc_window->hwc_window_backend == hwc_window_backend) - return private_hwc_window; - } - - return NULL; -} - INTERN tdm_error tdm_output_init(tdm_private_display *private_display) { @@ -1563,614 +1549,29 @@ tdm_output_create_capture(tdm_output *output, tdm_error *error) return capture; } -/* LCOV_EXCL_START */ -EXTERN tdm_hwc_window * -tdm_output_hwc_create_window(tdm_output *output, tdm_error *error) +EXTERN tdm_hwc * +tdm_output_get_hwc(tdm_output *output, tdm_error *error) { - tdm_hwc_window *hwc_window = NULL; + tdm_private_hwc *private_hwc = NULL; OUTPUT_FUNC_ENTRY_ERROR(); _pthread_mutex_lock(&private_display->lock); - if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 0, error); - else { - TDM_ERR("output(%p) not support HWC", private_output); + private_hwc = private_output->private_hwc; + if (!private_hwc) { if (error) *error = TDM_ERROR_BAD_REQUEST; - } - - _pthread_mutex_unlock(&private_display->lock); - - return hwc_window; -} - -EXTERN tdm_hwc_window * -tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error) -{ - tdm_hwc_window *hwc_window = NULL; - - OUTPUT_FUNC_ENTRY_ERROR(); - - _pthread_mutex_lock(&private_display->lock); - - if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 1, error); - else { - TDM_ERR("output(%p) not support HWC", private_output); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - } - - _pthread_mutex_unlock(&private_display->lock); - - return hwc_window; -} - -EXTERN tdm_error -tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window) -{ - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - ret = tdm_hwc_window_destroy_internal(hwc_window); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, - uint32_t num_wnds, uint32_t *num_types) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tdm_private_hwc_window **composited_wnds_frontend = NULL; - tdm_hwc_window **composited_wnds_backend = NULL; - int i; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_validate) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - if (num_wnds == 0) { - ret = func_output->output_hwc_validate(private_output->output_backend, NULL, 0, num_types); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; - } - - composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *)); - if (!composited_wnds_backend) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds; - - for (i = 0; i < num_wnds; i++) - composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend; - - ret = func_output->output_hwc_validate(private_output->output_backend, composited_wnds_backend, num_wnds, num_types); - - free(composited_wnds_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_set_need_validate_handler(tdm_output *output, - tdm_output_need_validate_handler hndl) -{ - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(hndl != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - /* there's no reason to allow this */ - if (private_output->need_validate.hndl) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OPERATION_FAILED; - } - - private_output->need_validate.hndl = hndl; - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_get_changed_composition_types(tdm_output *output, - uint32_t *num_elements, - tdm_hwc_window **hwc_window, - tdm_hwc_window_composition *composition_types) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tdm_private_hwc_window * private_hwc_window = NULL; - int i = 0; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_changed_composition_types) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_get_changed_composition_types(private_output->output_backend, - num_elements, hwc_window, composition_types); - if (ret != TDM_ERROR_NONE) { - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - if (hwc_window == NULL || composition_types == NULL) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - - for (i = 0; i < *num_elements; i++) { - - private_hwc_window = _tdm_output_find_private_hwc_window(private_output, hwc_window[i]); - - if (private_hwc_window == NULL) { - TDM_ERR("failed! This should never happen!"); - func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window[i]); - *num_elements = 0; - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OPERATION_FAILED; - } - - hwc_window[i] = (tdm_hwc_window*)private_hwc_window; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tdm_error -tdm_output_hwc_accept_changes(tdm_output *output) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_validate) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_accept_changes(private_output->output_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tbm_surface_queue_h -tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tbm_surface_queue_h queue = NULL; - - OUTPUT_FUNC_ENTRY_ERROR(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - _pthread_mutex_unlock(&private_display->lock); - return NULL; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_target_buffer_queue) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); return NULL; } - queue = func_output->output_hwc_get_target_buffer_queue(private_output->output_backend, error); - - _pthread_mutex_unlock(&private_display->lock); - - return queue; -} - -EXTERN tdm_error -tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) { - char str[TDM_PATH_LEN]; - static int i; - snprintf(str, TDM_PATH_LEN, "target_window_%d_%03d", - private_output->index, i++); - tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str); - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_set_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_set_client_target_buffer(private_output->output_backend, target_buffer, damage); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_unset_client_target_buffer(tdm_output *output) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_unset_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_unset_client_target_buffer(private_output->output_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static void -_tdm_output_hwc_layer_commit_handler(tdm_layer *layer, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler = (tdm_private_output_hwc_target_buffer_commit_handler *)user_data; - tdm_output_hwc_target_buffer_commit_handler func = output_hwc_target_buffer_commit_handler->func; - tdm_output *output = (tdm_output *)output_hwc_target_buffer_commit_handler->private_output; - void *data = output_hwc_target_buffer_commit_handler->user_data; - - func(output, sequence, tv_sec, tv_usec, data); - - free(output_hwc_target_buffer_commit_handler); -} - -tdm_error -tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data) -{ - tdm_private_module *private_module; - tdm_func_output *func_output; - tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler; - tdm_layer *layer = NULL; - tdm_private_layer *private_layer; - const tdm_output_mode *mode; - tbm_surface_h buffer; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_client_target_buffer_layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - layer = func_output->output_hwc_get_client_target_buffer_layer(private_output->output_backend, - &ret); - if (!layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("no assigned layer!!"); - return TDM_ERROR_INVALID_PARAMETER; - } - - private_layer = (tdm_private_layer*)layer; - - if (!func_output->output_hwc_get_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - buffer = func_output->output_hwc_get_client_target_buffer(private_output->output_backend, - &ret); - if (buffer) - ret = tdm_layer_set_buffer_internal(private_layer, buffer); - else - ret = tdm_layer_unset_buffer_internal(private_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - if (private_output->need_set_target_info) { - mode = private_output->current_mode; - private_output->target_buffer_info.src_config.size.h = mode->hdisplay; - private_output->target_buffer_info.src_config.size.v = mode->vdisplay; - private_output->target_buffer_info.src_config.pos.x = 0; - private_output->target_buffer_info.src_config.pos.y = 0; - private_output->target_buffer_info.src_config.pos.w = mode->hdisplay; - private_output->target_buffer_info.src_config.pos.h = mode->vdisplay; - private_output->target_buffer_info.dst_pos.x = 0; - private_output->target_buffer_info.dst_pos.y = 0; - private_output->target_buffer_info.dst_pos.w = mode->hdisplay; - private_output->target_buffer_info.dst_pos.h = mode->vdisplay; - private_output->target_buffer_info.transform = TDM_TRANSFORM_NORMAL; - - ret = tdm_layer_set_info_internal(private_layer, &private_output->target_buffer_info); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - private_output->need_set_target_info = 0; - } - - output_hwc_target_buffer_commit_handler = calloc(1, sizeof(tdm_private_output_hwc_target_buffer_commit_handler)); - if (!output_hwc_target_buffer_commit_handler) { - TDM_ERR("failed: alloc memory"); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - output_hwc_target_buffer_commit_handler->private_output = private_output; - output_hwc_target_buffer_commit_handler->func = func; - output_hwc_target_buffer_commit_handler->user_data = user_data; - - ret = tdm_layer_commit_internal(private_layer, _tdm_output_hwc_layer_commit_handler, output_hwc_target_buffer_commit_handler); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(target buffer)"); - free(output_hwc_target_buffer_commit_handler); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tdm_error -tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats, - int *count) -{ - tdm_private_module *private_module; - tdm_func_output *func_output; - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_video_supported_formats) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_get_video_supported_formats( - private_output->output_backend, formats, count); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static int -_is_hwc_output_still_existed(tdm_private_output *private_output) -{ - tdm_private_module *private_module = private_output->private_module; - tdm_private_output *o = NULL; - - LIST_FOR_EACH_ENTRY(o, &private_module->output_list, link) { - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - continue; - - if (o == private_output) - goto exist; - } - - return 0; - -exist: - return 1; -} - -/* gets called on behalf of the ecore-main-loop thread */ -INTERN void -tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) -{ - tdm_private_output *private_output = object; - - TDM_RETURN_IF_FAIL(private_output != NULL); - - _pthread_mutex_lock(&private_display->lock); - - /* as we get 'private_output' within an event, an output this 'private_output' - * points to can be destroyed already */ - if (!_is_hwc_output_still_existed(private_output)) { - _pthread_mutex_unlock(&private_display->lock); - return; - } + if (error) + *error = TDM_ERROR_NONE; _pthread_mutex_unlock(&private_display->lock); - TDM_INFO("tdm-backend asks for revalidation for the output:%p.", private_output); - - if (private_output->need_validate.hndl) - private_output->need_validate.hndl((tdm_output*)private_output); -} - -/* gets called on behalf of the tdm-thread */ -static tdm_error -_need_validate_handler(int fd, tdm_event_loop_mask mask, void *user_data) -{ - tdm_thread_cb_need_validate ev; - tdm_private_output *private_output; - tdm_error ret; - uint64_t value; - - private_output = (tdm_private_output *)user_data; - - if (read(private_output->need_validate.event_fd, &value, sizeof(value)) < 0) { - TDM_ERR("error while trying to read from a need_validate.event_fd fd."); - return TDM_ERROR_OPERATION_FAILED; - } - - memset(&ev, 0, sizeof ev); - ev.base.type = TDM_THREAD_CB_NEED_VALIDATE; - ev.base.length = sizeof ev; - ev.base.object_stamp = private_output->stamp; - ev.base.data = NULL; - ev.base.sync = 0; - - ret = tdm_thread_cb_call(private_output, &ev.base, 1); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - TDM_INFO("tdm-thread: get a 'need to revalidate' event for the ouptut:%p.", private_output); - - /* who cares about this? */ - return TDM_ERROR_NONE; -} - -INTERN tdm_error -tdm_output_need_validate_event_init(tdm_output *output) -{ - int fd; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - return TDM_ERROR_BAD_REQUEST; - } - - /* build in eventfd fds into event_loop listened & handled by the tdm-thread */ - fd = eventfd(0, 0); - TDM_WARNING_IF_FAIL(fd >= 0); - - private_output->need_validate.event_source = tdm_event_loop_add_fd_handler(private_display, - fd, TDM_EVENT_LOOP_READABLE, _need_validate_handler, private_output, &ret); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - private_output->need_validate.event_fd = fd; - - TDM_INFO("register an output:%p for the revalidation, event_fd:%d.", private_output, fd); - - return ret; + return private_hwc; } INTERN tdm_error diff --git a/src/tdm_private.h b/src/tdm_private.h index 22c984c..5e1ed84 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -93,6 +93,11 @@ tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp tdm_private_output * tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend); +void * +tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp); +tdm_private_hwc * +tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_backend); + tdm_error tdm_output_init(tdm_private_display *private_display); @@ -104,8 +109,6 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data); -tdm_error -tdm_output_cb_need_validate(tdm_private_output *private_output); void tdm_output_vblank_print_wait_information(tdm_private_output *private_output, void *user_data); @@ -118,10 +121,6 @@ tdm_error tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value); tdm_error -tdm_output_need_validate_event_init(tdm_output *output); -void -tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); -tdm_error tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int mode); void @@ -168,9 +167,11 @@ tdm_pp_create_internal(tdm_private_module *private_module, tdm_error *error); void tdm_pp_destroy_internal(tdm_private_pp *private_pp); -tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error *error); tdm_error +tdm_hwc_init(tdm_private_display *private_display); +tdm_hwc_window * +tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error); +void tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window); tdm_error diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 980ebfe..37adf72 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -100,6 +100,7 @@ typedef struct _tdm_private_module tdm_private_module; typedef struct _tdm_private_display tdm_private_display; typedef struct _tdm_private_output tdm_private_output; typedef struct _tdm_private_layer tdm_private_layer; +typedef struct _tdm_private_hwc tdm_private_hwc; typedef struct _tdm_private_hwc_window tdm_private_hwc_window; typedef struct _tdm_private_pp tdm_private_pp; typedef struct _tdm_private_capture tdm_private_capture; @@ -110,8 +111,7 @@ typedef struct _tdm_private_output_change_handler tdm_private_output_change_hand typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler; typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; -typedef struct _tdm_private_hwc_window_commit_handler tdm_private_hwc_window_commit_handler; -typedef struct _tdm_private_output_hwc_target_buffer_window_commit_handler tdm_private_output_hwc_target_buffer_commit_handler; +typedef struct _tdm_private_hwc_commit_handler tdm_private_hwc_commit_handler; typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; @@ -130,6 +130,7 @@ struct _tdm_private_module { tdm_func_display func_display; tdm_func_output func_output; tdm_func_layer func_layer; + tdm_func_hwc func_hwc; tdm_func_hwc_window func_hwc_window; tdm_func_pp func_pp; tdm_func_capture func_capture; @@ -196,7 +197,6 @@ struct _tdm_private_output { int regist_dpms_cb; struct list_head layer_list; - struct list_head hwc_window_list; struct list_head capture_list; struct list_head vblank_handler_list; struct list_head output_commit_handler_list; @@ -214,13 +214,6 @@ struct _tdm_private_output { void **layers_ptr; - struct { - /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ - tdm_output_need_validate_handler hndl; - int event_fd; - tdm_event_loop_source *event_source; - } need_validate; - tdm_info_layer target_buffer_info; /* layer_info for the target_buffer */ /* calling a output commit per a vblank */ @@ -232,6 +225,7 @@ struct _tdm_private_output { /* hwc */ int need_set_target_info; + tdm_private_hwc *private_hwc; }; struct _tdm_private_layer { @@ -271,14 +265,30 @@ struct _tdm_private_layer { unsigned int fps_count; }; -struct _tdm_private_hwc_window { +struct _tdm_private_hwc { struct list_head link; + tdm_private_module *private_module; + int index; + double stamp; - tdm_private_display *private_display; tdm_private_output *private_output; + struct list_head hwc_window_list; + struct list_head hwc_commit_handler_list; + + int regist_commit_cb; + + tdm_hwc *hwc_backend; +}; + +struct _tdm_private_hwc_window { + struct list_head link; + + tdm_private_module *private_module; + + tdm_private_hwc *private_hwc; tdm_hwc_window *hwc_window_backend; }; @@ -394,16 +404,14 @@ struct _tdm_private_output_commit_handler { pid_t owner_tid; }; -struct _tdm_private_hwc_window_commit_handler { - tdm_private_hwc_window *private_hwc_window; - tdm_hwc_window_commit_handler func; - void *user_data; -}; +struct _tdm_private_hwc_commit_handler { + struct list_head link; -struct _tdm_private_output_hwc_target_buffer_window_commit_handler { - tdm_private_output *private_output; - tdm_output_hwc_target_buffer_commit_handler func; + tdm_private_hwc *private_hwc; + tdm_hwc_commit_handler func; void *user_data; + + pid_t owner_tid; }; struct _tdm_private_layer_commit_handler { @@ -458,7 +466,7 @@ typedef enum { TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, TDM_THREAD_CB_VBLANK_CREATE, - TDM_THREAD_CB_NEED_VALIDATE, + TDM_THREAD_CB_HWC_COMMIT, TDM_THREAD_CB_MAX, } tdm_thread_cb_type; @@ -471,7 +479,7 @@ typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; typedef struct _tdm_thread_cb_vblank_create tdm_thread_cb_vblank_create; -typedef struct _tdm_thread_cb_need_validate tdm_thread_cb_need_validate; +typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_hwc_commit; struct _tdm_thread_cb_base { tdm_thread_cb_type type; @@ -518,10 +526,6 @@ struct _tdm_thread_cb_vblank_create { double vblank_stamp; }; -struct _tdm_thread_cb_need_validate { - tdm_thread_cb_base base; -}; - struct argument_details { char type; int nullable; diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ea891a2..997d772 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -459,7 +459,7 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: case TDM_THREAD_CB_VBLANK_CREATE: - case TDM_THREAD_CB_NEED_VALIDATE: + case TDM_THREAD_CB_HWC_COMMIT: /* this event comes from other thread. so we don't need to propagate this to other thread */ ret = tdm_thread_cb_call(NULL, base, 0); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); diff --git a/utests/Makefile.am b/utests/Makefile.am index 7c22473..7aed5c8 100644 --- a/utests/Makefile.am +++ b/utests/Makefile.am @@ -11,8 +11,6 @@ tdm_utests_SOURCES = \ src/ut_tdm_display.cpp \ src/ut_tdm_output.cpp \ src/ut_tdm_layer.cpp \ - src/ut_tdm_output_hwc.cpp \ - src/ut_tdm_hwc_window.cpp \ src/ut_tdm_client.cpp \ src/ut_tdm_backend_env.cpp \ src/ut_tdm_backend_display.cpp \ diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index 12be19c..fb1b190 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -43,7 +43,6 @@ public: tdm_error error; tdm_hwc_window **hwc_wins; - tdm_hwc_window *video_hwc_win; int hwc_count; }; @@ -67,13 +66,10 @@ void TDMHwcWindow::SetUp(void) for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { for (int w = 0; w < HWC_WIN_NUM; w++) { - hw = tdm_output_hwc_create_window(outputs[w], &error); + hw = tdm_hwc_create_window(outputs[w], &error); ASSERT_EQ(TDM_ERROR_NONE, error); hwc_wins[hwc_count++] = hw; } - - if (!video_hwc_win) - video_hwc_win = tdm_output_hwc_create_video_window(outputs[o], &error); } } } @@ -81,26 +77,16 @@ void TDMHwcWindow::SetUp(void) void TDMHwcWindow::TearDown(void) { for (int w = 0; w < hwc_count; w++) - tdm_output_hwc_destroy_window(outputs[0], hwc_wins[w]); - - if (video_hwc_win) - tdm_output_hwc_destroy_window(outputs[0], video_hwc_win); + tdm_hwc_window_destroy(hwc_wins[w]); TDMOutput::TearDown(); } -/* tdm_error tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); */ +/* void tdm_hwc_window_destroy(tdm_hwc_window *hwc_window); */ +/* TEST_P(TDMHwcWindow, DestroyWindowFailNull) { - TDM_UT_SKIP_FLAG(has_outputs); - - for (int o = 0; o < output_count; o++) { - if (ut_tdm_output_is_hwc_enable(outputs[o])) { - /* test: hw is NULL*/ - error = tdm_output_hwc_destroy_window(outputs[o], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } + tdm_hwc_window_destroy(NULL); } TEST_P(TDMHwcWindow, DestroyWindowSuccessful) @@ -111,27 +97,27 @@ TEST_P(TDMHwcWindow, DestroyWindowSuccessful) for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - hw = tdm_output_hwc_create_window(outputs[o], &error); + hw = tdm_hwc_create_window(outputs[o], &error); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_destroy_window(outputs[o], hw); + error = tdm_hwc_window_destroy(outputs[o], hw); ASSERT_EQ(TDM_ERROR_NONE, error); } } } +*/ - -/* tbm_surface_queue_h tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ +/* tbm_surface_queue_h tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ TEST_P(TDMHwcWindow, GetBufferQueueFailNull) { TDM_UT_SKIP_FLAG(has_outputs); tbm_surface_queue_h queue = NULL; - queue = tdm_hwc_window_get_tbm_buffer_queue(NULL, &error); + queue = tdm_hwc_window_get_buffer_queue(NULL, &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); - queue = tdm_hwc_window_get_tbm_buffer_queue(NULL, NULL); + queue = tdm_hwc_window_get_buffer_queue(NULL, NULL); ASSERT_EQ(NULL, queue); } @@ -152,12 +138,12 @@ TEST_P(TDMHwcWindow, GetBufferQueueSuccessful) error = tdm_hwc_window_set_info(hwc_wins[w], &info); ASSERT_EQ(TDM_ERROR_NONE, error); - queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[w], &error); + queue = tdm_hwc_window_get_buffer_queue(hwc_wins[w], &error); tbm_surface_queue_destroy(queue); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_NE(NULL, queue); - queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[w], NULL); + queue = tdm_hwc_window_get_buffer_queue(hwc_wins[w], NULL); tbm_surface_queue_destroy(queue); ASSERT_NE(NULL, queue); } @@ -197,12 +183,12 @@ TEST_P(TDMHwcWindow, SetCompositionTypeFailInvalieCompositionType) } } -/* tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage); */ +/* tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); */ TEST_P(TDMHwcWindow, SetBufferDamageFailNullHwcWindow) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_region damage = {.num_rects = 0, .rects = NULL}; error = tdm_hwc_window_set_buffer_damage(NULL, damage); ASSERT_NE(TDM_ERROR_NONE, error); @@ -212,7 +198,7 @@ TEST_P(TDMHwcWindow, SetBufferDamageFailNullDamageRects) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 1, .rects = NULL}; + tdm_region damage = {.num_rects = 1, .rects = NULL}; for (int w = 0; w < hwc_count; w++) { error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); @@ -226,7 +212,7 @@ TEST_P(TDMHwcWindow, SetBufferDamageSuccessful) TDM_UT_SKIP_FLAG(has_outputs); tdm_pos const rects[1] = {0}; - tdm_hwc_region damage = {.num_rects = 1, .rects = rects}; + tdm_region damage = {.num_rects = 1, .rects = rects}; for (int w = 0; w < hwc_count; w++) { error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); @@ -292,92 +278,8 @@ TEST_P(TDMHwcWindow, SetBufferSuccessful) } } -/* tdm_error tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); */ -TEST_P(TDMHwcWindow, SetFlagsFailNull) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - error = tdm_hwc_window_set_flags(NULL, flag); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_P(TDMHwcWindow, SetFlagsSuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - for (int w = 0; w < hwc_count; w++) { - - error = tdm_hwc_window_set_flags(hwc_wins[w], flag); - ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); - } -} - -/* tdm_error tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); */ -TEST_P(TDMHwcWindow, UnsetFlagsFailNull) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - error = tdm_hwc_window_unset_flags(NULL, flag); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_P(TDMHwcWindow, UnsetFlagsSuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - for (int w = 0; w < hwc_count; w++) { - - error = tdm_hwc_window_unset_flags(hwc_wins[w], flag); - ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); - } -} - -/* tdm_error tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); */ -TEST_P(TDMHwcWindow, VideoGetCapabilityFailNull) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_video_capability video_capability; - - error = tdm_hwc_window_video_get_capability(NULL, &video_capability); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (hwc_count > 0) { - error = tdm_hwc_window_video_get_capability(hwc_wins[0], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } - -} - -TEST_P(TDMHwcWindow, VideoGetCapabilitySuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_video_capability video_capability; - - for (int w = 0; w < hwc_count; w++) { - /* hwc_window with TDM_COMPOSITION_CLIENT dosn't support tdm_hwc_window_video_get_capability()*/ - error = tdm_hwc_window_video_get_capability(hwc_wins[w], &video_capability); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (video_hwc_win != NULL) { - error = tdm_hwc_window_video_get_capability(video_hwc_win, &video_capability); - ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); - } - } -} - - -/* tdm_hwc_window_video_get_available_properties() */ +/* tdm_hwc_get_available_properties() */ +/* TEST_P(TDMHwcWindow, GetAvailablePropertiesFailNullWin) { TDM_UT_SKIP_FLAG(has_outputs); @@ -386,13 +288,13 @@ TEST_P(TDMHwcWindow, GetAvailablePropertiesFailNullWin) const tdm_prop *props; int count; - error = tdm_hwc_window_video_get_available_properties(NULL, &props, &count); + error = tdm_hwc_get_available_properties(NULL, &props, &count); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, NULL, &count); + error = tdm_hwc_get_available_properties(video_hwc_win, NULL, &count); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, &props, NULL); + error = tdm_hwc_get_available_properties(video_hwc_win, &props, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -405,11 +307,12 @@ TEST_P(TDMHwcWindow, GetAvailablePropertiesSuccess) const tdm_prop *props; int count; - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, &props, &count); + error = tdm_hwc_get_available_properties(video_hwc_win, &props, &count); ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); } +*/ -/* tdm_hwc_window_video_get_property() */ +/* tdm_hwc_window_get_property() */ TEST_P(TDMHwcWindow, GetPropertyFailNull) { TDM_UT_SKIP_FLAG(has_outputs); @@ -418,10 +321,10 @@ TEST_P(TDMHwcWindow, GetPropertyFailNull) tdm_value value; int id = 1; - error = tdm_hwc_window_video_get_property(NULL, id, &value); + error = tdm_hwc_window_get_property(NULL, id, &value); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_property(video_hwc_win, id, NULL); + error = tdm_hwc_window_get_property(video_hwc_win, id, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -433,11 +336,11 @@ TEST_P(TDMHwcWindow, GetPropertyFailWrongId) tdm_value value; int id = INT_MAX; - error = tdm_hwc_window_video_get_property(video_hwc_win, id, &value); + error = tdm_hwc_window_get_property(video_hwc_win, id, &value); ASSERT_NE(TDM_ERROR_NONE, error); } -/* tdm_hwc_window_video_set_property() */ +/* tdm_hwc_window_set_property() */ TEST_P(TDMHwcWindow, SetPropertyFailNull) { TDM_UT_SKIP_FLAG(has_outputs); @@ -446,7 +349,7 @@ TEST_P(TDMHwcWindow, SetPropertyFailNull) tdm_value value; int id = 1; - error = tdm_hwc_window_video_set_property(NULL, id, value); + error = tdm_hwc_window_set_property(NULL, id, value); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -458,7 +361,7 @@ TEST_P(TDMHwcWindow, SetPropertyFailWrongId) tdm_value value; int id = INT_MAX; - error = tdm_hwc_window_video_set_property(video_hwc_win, id, value); + error = tdm_hwc_window_set_property(video_hwc_win, id, value); ASSERT_NE(TDM_ERROR_NONE, error); } diff --git a/utests/src/ut_tdm_output_hwc.cpp b/utests/src/ut_tdm_output_hwc.cpp index e84860d..29019c5 100644 --- a/utests/src/ut_tdm_output_hwc.cpp +++ b/utests/src/ut_tdm_output_hwc.cpp @@ -57,15 +57,16 @@ void TDMOutputHwc::TearDown(void) TDMOutput::TearDown(); } -/* tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); */ +/* tdm_hwc_window * tdm_hwc_create_window(tdm_output *output, tdm_error *error); */ TEST_P(TDMOutputHwc, CreateWindowFailNull) { TDM_UT_SKIP_FLAG(has_outputs); - ASSERT_EQ(NULL, tdm_output_hwc_create_window(NULL, &error)); + ASSERT_EQ(NULL, tdm_hwc_create_window(NULL, &error)); ASSERT_NE(TDM_ERROR_NONE, error); } +/* TEST_P(TDMOutputHwc, CreateWindowSuccessful) { TDM_UT_SKIP_FLAG(has_outputs); @@ -74,40 +75,40 @@ TEST_P(TDMOutputHwc, CreateWindowSuccessful) for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - hw = tdm_output_hwc_create_window(outputs[o], &error); - ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_destroy_window(outputs[o], hw); + hw = tdm_hwc_create_window(hwc[o], &error); ASSERT_EQ(TDM_ERROR_NONE, error); + tdm_hwc_window_destroy(hw); } else { - ASSERT_EQ(NULL, tdm_output_hwc_create_window(outputs[o], &error)); + ASSERT_EQ(NULL, tdm_hwc_create_window(outputs[o], &error)); ASSERT_NE(TDM_ERROR_NONE, error); } } } +*/ -/* tdm_error tdm_output_hwc_set_client_target_buffer(tdm_output *output, - tbm_surface_h target_buffer, tdm_hwc_region damage, +/* tdm_error tdm_hwc_set_client_target_buffer(tdm_output *output, + tbm_surface_h target_buffer, tdm_region damage, tdm_hwc_window *composited_wnds, uint32_t num_wnds); */ /* TDOO: need to be fixed TEST_P(TDMOutputHwc, SetClientTargetBufferFailNullOutput) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region reg; + tdm_region reg; tbm_surface_h target_buff = CreateBufferForOutput(0); - error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 ); + error = tdm_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 ); tbm_surface_internal_destroy(target_buff); ASSERT_NE(TDM_ERROR_NONE, error); } TEST_P(TDMOutputHwc, SetClientTargetBufferFailNoHwc) { - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_region damage = {.num_rects = 0, .rects = NULL}; for (int o = 0; o < output_count; o++) { tbm_surface_h target_buff = CreateBufferForOutput(i); ASSERT_NE(NULL, target_buff); - error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); + error = tdm_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); tbm_surface_internal_destroy(target_buff); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -117,18 +118,18 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulSetBuff) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_region damage = {.num_rects = 0, .rects = NULL}; for (int o = 0; o < output_count; o++) { tbm_surface_h target_buff = CreateBufferForOutput(i); ASSERT_NE(NULL, target_buff); if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, + error = tdm_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); tbm_surface_internal_destroy(target_buff); ASSERT_EQ(TDM_ERROR_NONE, error); } else { - error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, + error = tdm_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); tbm_surface_internal_destroy(target_buff); ASSERT_NE(TDM_ERROR_NONE, error); @@ -140,15 +141,15 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_region damage = {.num_rects = 0, .rects = NULL}; for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_set_client_target_buffer(outputs[o], NULL, damage, + error = tdm_hwc_set_client_target_buffer(outputs[o], NULL, damage, NULL, 0); ASSERT_EQ(TDM_ERROR_NONE, error); } else { - error = tdm_output_hwc_set_client_target_buffer(outputs[o], NULL, damage, + error = tdm_hwc_set_client_target_buffer(outputs[o], NULL, damage, NULL, 0); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -156,18 +157,19 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) } */ -/* tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); */ +/* tbm_surface_queue_h tdm_hwc_get_client_target_buffer_queue(tdm_output *output, tdm_error *error); */ +/* TEST_P(TDMOutputHwc, GetTargetBufferQueueFailNullObject) { TDM_UT_SKIP_FLAG(has_outputs); tbm_surface_queue_h queue = NULL; - queue = tdm_output_hwc_get_target_buffer_queue(NULL, &error); + queue = tdm_hwc_get_client_target_buffer_queue(NULL, &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); - queue = tdm_output_hwc_get_target_buffer_queue(NULL, NULL); + queue = tdm_hwc_get_client_target_buffer_queue(NULL, NULL); ASSERT_EQ(NULL, queue); } @@ -178,11 +180,12 @@ TEST_P(TDMOutputHwc, GetTargetBufferQueueFainNoHwc) tbm_surface_queue_h queue = NULL; for (int o = 0; o < output_count; o++) { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); } } +*/ TEST_P(TDMOutputHwc, GetTargetBufferQueueSuccessful) { @@ -192,28 +195,28 @@ TEST_P(TDMOutputHwc, GetTargetBufferQueueSuccessful) for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], &error); tbm_surface_queue_destroy(queue); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_NE(NULL, queue); - queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], NULL); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], NULL); tbm_surface_queue_destroy(queue); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_NE(NULL, queue); } else { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); - queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], NULL); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], NULL); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); } } } -/* tdm_error tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, +/* tdm_error tdm_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types); */ /* TODO: fix the validate test later. TEST_P(TDMOutputHwc, ValidateFailNull) @@ -221,11 +224,11 @@ TEST_P(TDMOutputHwc, ValidateFailNull) TDM_UT_SKIP_FLAG(has_outputs); uint32_t num_types; - error = tdm_output_hwc_validate(NULL, NULL, 0, &num_types); + error = tdm_hwc_validate(NULL, NULL, 0, &num_types); ASSERT_NE(TDM_ERROR_NONE, error); if (outputs[0]) { - error = tdm_output_hwc_validate(outputs[0], NULL, 0, NULL); + error = tdm_hwc_validate(outputs[0], NULL, 0, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -237,7 +240,7 @@ TEST_P(TDMOutputHwc, ValidateFailNoHwc) uint32_t num_types; for (int o = 0; o < output_count; o++) { - error = tdm_output_hwc_validate(outputs[o], &num_types); + error = tdm_hwc_validate(outputs[o], &num_types); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -249,31 +252,31 @@ TEST_P(TDMOutputHwc, ValidateSuccessful) uint32_t num_types; for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_validate(outputs[o], &num_types); + error = tdm_hwc_validate(outputs[o], &num_types); ASSERT_EQ(TDM_ERROR_NONE, error); } else { - error = tdm_output_hwc_validate(outputs[o], &num_types); + error = tdm_hwc_validate(outputs[o], &num_types); ASSERT_NE(TDM_ERROR_NONE, error); } } } TODO: */ -/* tdm_error tdm_output_hwc_get_changed_composition_types(tdm_output *output, +/* tdm_error tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_window, tdm_hwc_window_composition *composition_types); */ - +/* TEST_P(TDMOutputHwc, GetChangedCompositionTypesFailNull) { TDM_UT_SKIP_FLAG(has_outputs); uint32_t num_elements; - error = tdm_output_hwc_get_changed_composition_types(NULL, &num_elements, NULL, NULL); + error = tdm_hwc_get_changed_composition_types(NULL, &num_elements, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); if (outputs[0]) { - error = tdm_output_hwc_get_changed_composition_types(outputs[0], NULL, NULL, NULL); + error = tdm_hwc_get_changed_composition_types(outputs[0], NULL, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -285,11 +288,11 @@ TEST_P(TDMOutputHwc, GetChangedCompositionTypesFailNoHwc) uint32_t get_num = 10; for (int o = 0; o < output_count; o++) { - error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + error = tdm_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } - +*/ /* TODO: fix the validate test later. TEST_P(TDMHwcWindow, GetChangedCompositionTypesSuccessful) { @@ -309,48 +312,48 @@ TEST_P(TDMHwcWindow, GetChangedCompositionTypesSuccessful) for (int i = 0; i < output_count; i++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_validate(outputs[o], &validate_num); + error = tdm_hwc_validate(outputs[o], &validate_num); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + error = tdm_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_EQ(get_num, validate_num); hwc_wnds = (tdm_hwc_window **)calloc(get_num, sizeof(tdm_hwc_window *)); composition_types = (tdm_hwc_window_composition *)calloc(get_num, sizeof(tdm_hwc_window_composition)); - error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, hwc_wnds, composition_types); + error = tdm_hwc_get_changed_composition_types(outputs[o], &get_num, hwc_wnds, composition_types); free(hwc_wnds); free(composition_types); ASSERT_EQ(TDM_ERROR_NONE, error); } else { - error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + error = tdm_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } } */ -/* tdm_error tdm_output_hwc_accept_changes(tdm_output *output); */ - +/* tdm_error tdm_hwc_accept_changes(tdm_hwc *hwc); */ +/* TEST_P(TDMOutputHwc, AcceptChangesFailNull) { TDM_UT_SKIP_FLAG(has_outputs); - error = tdm_output_hwc_accept_changes(NULL); + error = tdm_hwc_accept_changes(NULL); ASSERT_NE(TDM_ERROR_NONE, error); } TEST_P(TDMOutputHwc, AcceptChangesFailNoHwc) { for (int o = 0; o < output_count; o++) { - error = tdm_output_hwc_accept_changes(outputs[o]); + error = tdm_hwc_accept_changes(outputs[o]); ASSERT_NE(TDM_ERROR_NONE, error); } } - +*/ /* TODO: fix the validate test later. TEST_P(TDMHwcWindow, AcceptChangesSuccessful) { @@ -365,11 +368,11 @@ TEST_P(TDMHwcWindow, AcceptChangesSuccessful) for (int i = 0; i < output_count; i++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_validate(outputs[o], &validate_num); + error = tdm_hwc_validate(outputs[o], &validate_num); ASSERT_EQ(TDM_ERROR_NONE, error); if (validate_num > 0) { - error = tdm_output_hwc_accept_changes(outputs[o]); + error = tdm_hwc_accept_changes(outputs[o]); ASSERT_EQ(TDM_ERROR_NONE, error); } } @@ -377,45 +380,15 @@ TEST_P(TDMHwcWindow, AcceptChangesSuccessful) } */ -/* tdm_hwc_window * tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); */ -TEST_P(TDMOutputHwc, CreateVideoWindowFailNull) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(NULL, &error)); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_P(TDMOutputHwc, CreateVideoWindowSuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window *hw = NULL; - - for (int o = 0; o < output_count; o++) { - if (ut_tdm_output_is_hwc_enable(outputs[o])) { - hw = tdm_output_hwc_create_video_window(outputs[o], &error); - if (error != TDM_ERROR_NOT_IMPLEMENTED) { - ASSERT_EQ(TDM_ERROR_NONE, error); - ASSERT_NE(NULL, hw); - error = tdm_output_hwc_destroy_window(outputs[o], hw); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - } else { - ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(outputs[o], &error)); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} - -/* tdm_output_hwc_get_video_supported_formats() */ +/* tdm_hwc_get_supported_formats() */ +/* TEST_P(TDMOutputHwc, GetVideoSupportedFormatsFailNull) { TDM_UT_SKIP_FLAG(has_outputs); tdm_error error; - error = tdm_output_hwc_get_video_supported_formats(NULL, NULL, NULL); + error = tdm_hwc_get_supported_formats(NULL, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -429,18 +402,19 @@ TEST_P(TDMOutputHwc, GetVideoSupportedFormatsSuccessful) for (int o = 0; o < output_count; o++) { if (ut_tdm_output_is_hwc_enable(outputs[o])) { - error = tdm_output_hwc_get_video_supported_formats(outputs[o], &formats, &count); + error = tdm_hwc_get_supported_formats(outputs[o], &formats, &count); if (error != TDM_ERROR_NOT_IMPLEMENTED) { ASSERT_EQ(TDM_ERROR_NONE, error); if (count > 0) ASSERT_NE(NULL, formats); } } else { - error = tdm_output_hwc_get_video_supported_formats(outputs[o], &formats, &count); + error = tdm_hwc_get_supported_formats(outputs[o], &formats, &count); ASSERT_NE(TDM_ERROR_NONE, error); } } } +*/ #ifdef TDM_UT_TEST_WITH_PARAMS INSTANTIATE_TEST_CASE_P(TDMOutputHwcParams,