1/* 2* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. 3* 4* Redistribution and use in source and binary forms, with or without modification, are permitted 5* provided that the following conditions are met: 6* * Redistributions of source code must retain the above copyright notice, this list of 7* conditions and the following disclaimer. 8* * Redistributions in binary form must reproduce the above copyright notice, this list of 9* conditions and the following disclaimer in the documentation and/or other materials provided 10* with the distribution. 11* * Neither the name of The Linux Foundation nor the names of its contributors may be used to 12* endorse or promote products derived from this software without specific prior written 13* permission. 14* 15* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 21* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23*/ 24 25/*! @file display_interface.h 26 @brief Interface file for display device which represents a physical panel or an output buffer 27 where contents can be rendered. 28 29 @details Display device is used to send layer buffers for composition and get them rendered onto 30 the target device. Each display device represents a unique display target which may be either a 31 physical panel or an output buffer.. 32*/ 33#ifndef __DISPLAY_INTERFACE_H__ 34#define __DISPLAY_INTERFACE_H__ 35 36#include <stdint.h> 37#include <string> 38#include <vector> 39#include <utility> 40 41#include "layer_stack.h" 42#include "sdm_types.h" 43 44namespace sdm { 45 46typedef std::vector<std::pair<std::string, std::string>> AttrVal; 47 48/*! @brief This enum represents display device types where contents can be rendered. 49 50 @sa CoreInterface::CreateDisplay 51 @sa CoreInterface::IsDisplaySupported 52*/ 53enum DisplayType { 54 kPrimary, //!< Main physical display which is attached to the handheld device. 55 kHDMI, //!< HDMI physical display which is generally detachable. 56 kVirtual, //!< Contents would be rendered into the output buffer provided by the client 57 //!< e.g. wireless display. 58 kDisplayMax, 59}; 60 61/*! @brief This enum represents states of a display device. 62 63 @sa DisplayInterface::GetDisplayState 64 @sa DisplayInterface::SetDisplayState 65*/ 66enum DisplayState { 67 kStateOff, //!< Display is OFF. Contents are not rendered in this state. Client will not 68 //!< receive VSync events in this state. This is default state as well. 69 70 kStateOn, //!< Display is ON. Contents are rendered in this state. 71 72 kStateDoze, //!< Display is ON and it is configured in a low power state. 73 74 kStateDozeSuspend, 75 //!< Display is ON in a low power state and continue showing its current 76 //!< contents indefinitely until the mode changes. 77 78 kStateStandby, //!< Display is OFF. Client will continue to receive VSync events in this state 79 //!< if VSync is enabled. Contents are not rendered in this state. 80}; 81 82/*! @brief This enum represents flags to override detail enhancer parameters. 83 84 @sa DisplayInterface::SetDetailEnhancerData 85*/ 86enum DetailEnhancerOverrideFlags { 87 kOverrideDEEnable = 0x1, // Specifies to enable detail enhancer 88 kOverrideDESharpen1 = 0x2, // Specifies user defined Sharpening/smooth for noise 89 kOverrideDESharpen2 = 0x4, // Specifies user defined Sharpening/smooth for signal 90 kOverrideDEClip = 0x8, // Specifies user defined DE clip shift 91 kOverrideDELimit = 0x10, // Specifies user defined DE limit value 92 kOverrideDEThrQuiet = 0x20, // Specifies user defined DE quiet threshold 93 kOverrideDEThrDieout = 0x40, // Specifies user defined DE dieout threshold 94 kOverrideDEThrLow = 0x80, // Specifies user defined DE low threshold 95 kOverrideDEThrHigh = 0x100, // Specifies user defined DE high threshold 96 kOverrideDEFilterConfig = 0x200, // Specifies user defined scaling filter config 97 kOverrideDEMax = 0xFFFFFFFF, 98}; 99 100/*! @brief This enum represents Y/RGB scaling filter configuration. 101 102 @sa DisplayInterface::SetDetailEnhancerData 103*/ 104enum ScalingFilterConfig { 105 kFilterEdgeDirected, 106 kFilterCircular, 107 kFilterSeparable, 108 kFilterBilinear, 109 kFilterMax, 110}; 111 112/*! @brief This enum represents the quality level of the content. 113 114 @sa DisplayInterface::SetDetailEnhancerData 115*/ 116enum ContentQuality { 117 kContentQualityUnknown, // Default: high artifact and noise 118 kContentQualityLow, // Low quality content, high artifact and noise, 119 kContentQualityMedium, // Medium quality, medium artifact and noise, 120 kContentQualityHigh, // High quality content, low artifact and noise 121 kContentQualityMax, 122}; 123 124/*! @brief This enum represents the display port. 125 126 @sa DisplayInterface::GetDisplayPort 127*/ 128enum DisplayPort { 129 kPortDefault, 130 kPortDSI, // Display is connected to DSI port. 131 kPortDTV, // Display is connected to DTV port 132 kPortWriteBack, // Display is connected to writeback port 133 kPortLVDS, // Display is connected to LVDS port 134 kPortEDP, // Display is connected to EDP port 135 kPortDP, // Display is connected to DP port. 136}; 137 138/*! @brief This enum represents the events received by Display HAL. */ 139enum DisplayEvent { 140 kIdleTimeout, // Event triggered by Idle Timer. 141 kThermalEvent, // Event triggered by Thermal. 142}; 143 144/*! @brief This structure defines configuration for fixed properties of a display device. 145 146 @sa DisplayInterface::GetConfig 147 @sa DisplayInterface::SetConfig 148*/ 149struct DisplayConfigFixedInfo { 150 bool underscan = false; //!< If display support CE underscan. 151 bool secure = false; //!< If this display is capable of handling secure content. 152 bool is_cmdmode = false; //!< If panel is command mode panel. 153 bool hdr_supported = false; //!< if HDR is enabled 154 uint32_t max_luminance = 0; //!< From Panel's peak luminance 155 uint32_t average_luminance = 0; //!< From Panel's average luminance 156 uint32_t min_luminance = 0; //!< From Panel's blackness level 157}; 158 159/*! @brief This structure defines configuration for variable properties of a display device. 160 161 @sa DisplayInterface::GetConfig 162 @sa DisplayInterface::SetConfig 163*/ 164struct DisplayConfigVariableInfo { 165 uint32_t x_pixels = 0; //!< Total number of pixels in X-direction on the display panel. 166 uint32_t y_pixels = 0; //!< Total number of pixels in Y-direction on the display panel. 167 float x_dpi = 0.0f; //!< Dots per inch in X-direction. 168 float y_dpi = 0.0f; //!< Dots per inch in Y-direction. 169 uint32_t fps = 0; //!< Frame rate per second. 170 uint32_t vsync_period_ns = 0; //!< VSync period in nanoseconds. 171 bool is_yuv = false; //!< If the display output is in YUV format. 172}; 173 174/*! @brief Event data associated with VSync event. 175 176 @sa DisplayEventHandler::VSync 177*/ 178struct DisplayEventVSync { 179 int64_t timestamp = 0; //!< System monotonic clock timestamp in nanoseconds. 180}; 181 182/*! @brief The structure defines the user input for detail enhancer module. 183 184 @sa DisplayInterface::SetDetailEnhancerData 185*/ 186struct DisplayDetailEnhancerData { 187 uint32_t override_flags = 0; // flags to specify which data to be set. 188 uint16_t enable = 0; // Detail enchancer enable 189 int16_t sharpen_level1 = 0; // Sharpening/smooth strenght for noise 190 int16_t sharpen_level2 = 0; // Sharpening/smooth strenght for signal 191 uint16_t clip = 0; // DE clip shift 192 uint16_t limit = 0; // DE limit value 193 uint16_t thr_quiet = 0; // DE quiet threshold 194 uint16_t thr_dieout = 0; // DE dieout threshold 195 uint16_t thr_low = 0; // DE low threshold 196 uint16_t thr_high = 0; // DE high threshold 197 int32_t sharp_factor = 50; // sharp_factor specifies sharpness/smoothness level, 198 // range -100..100 positive for sharpness and negative for 199 // smoothness 200 ContentQuality quality_level = kContentQualityUnknown; 201 // Specifies context quality level 202 ScalingFilterConfig filter_config = kFilterEdgeDirected; 203 // Y/RGB filter configuration 204}; 205 206/*! @brief Display device event handler implemented by the client. 207 208 @details This class declares prototype for display device event handler methods which must be 209 implemented by the client. Display device will use these methods to notify events to the client. 210 Client must post heavy-weight event handling to a separate thread and unblock display manager 211 thread instantly. 212 213 @sa CoreInterface::CreateDisplay 214*/ 215class DisplayEventHandler { 216 public: 217 /*! @brief Event handler for VSync event. 218 219 @details This event is dispatched on every vertical synchronization. The event is disabled by 220 default. 221 222 @param[in] vsync \link DisplayEventVSync \endlink 223 224 @return \link DisplayError \endlink 225 226 @sa DisplayInterface::GetDisplayState 227 @sa DisplayInterface::SetDisplayState 228 */ 229 virtual DisplayError VSync(const DisplayEventVSync &vsync) = 0; 230 231 /*! @brief Event handler for Refresh event. 232 233 @details This event is dispatched to trigger a screen refresh. Client must call Prepare() and 234 Commit() in response to it from a separate thread. There is no data associated with this 235 event. 236 237 @return \link DisplayError \endlink 238 239 @sa DisplayInterface::Prepare 240 @sa DisplayInterface::Commit 241 */ 242 virtual DisplayError Refresh() = 0; 243 244 /*! @brief Event handler for CEC messages. 245 246 @details This event is dispatched to send CEC messages to the CEC HAL. 247 248 @param[in] message message to be sent 249 250 @return \link DisplayError \endlink 251 */ 252 virtual DisplayError CECMessage(char *message) = 0; 253 254 /*! @brief Event handler for events received by Display HAL. */ 255 virtual DisplayError HandleEvent(DisplayEvent event) = 0; 256 257 protected: 258 virtual ~DisplayEventHandler() { } 259}; 260 261struct PPDisplayAPIPayload; 262struct PPPendingParams; 263 264/*! @brief Display device interface. 265 266 @details This class defines display device interface. It contains methods which client shall use 267 to configure or submit layers for composition on the display device. This interface is created 268 during display device creation and remains valid until destroyed. 269 270 @sa CoreInterface::CreateDisplay 271 @sa CoreInterface::DestroyDisplay 272*/ 273class DisplayInterface { 274 public: 275 /*! @brief Method to determine hardware capability to compose layers associated with given frame. 276 277 @details Client shall send all layers associated with a frame targeted for current display 278 using this method and check the layers which can be handled completely in display manager. 279 280 Client shall mark composition type for one of the layer as kCompositionGPUTarget; the GPU 281 composed output would be rendered at the specified layer if some of the layers are not handled 282 by SDM. 283 284 Display manager will set each layer as kCompositionGPU or kCompositionSDE upon return. Client 285 shall render all the layers marked as kCompositionGPU using GPU. 286 287 This method can be called multiple times but only last call prevails. This method must be 288 followed by Commit(). 289 290 @param[inout] layer_stack \link LayerStack \endlink 291 292 @return \link DisplayError \endlink 293 294 @sa Commit 295 */ 296 virtual DisplayError Prepare(LayerStack *layer_stack) = 0; 297 298 /*! @brief Method to commit layers of a frame submitted in a former call to Prepare(). 299 300 @details Client shall call this method to submit layers for final composition. The composed 301 output would be displayed on the panel or written in output buffer. 302 303 Client must ensure that layer stack is same as previous call to Prepare. 304 305 This method shall be called only once for each frame. 306 307 In the event of an error as well, this call will cause any fences returned in the previous call 308 to Commit() to eventually become signaled, so the client's wait on fences can be released to 309 prevent deadlocks. 310 311 @param[in] layer_stack \link LayerStack \endlink 312 313 @return \link DisplayError \endlink 314 315 @sa Prepare 316 */ 317 virtual DisplayError Commit(LayerStack *layer_stack) = 0; 318 319 /*! @brief Method to flush any pending buffers/fences submitted previously via Commit() call. 320 321 @details Client shall call this method to request the Display manager to release all buffers and 322 respective fences currently in use. This operation may result in a blank display on the panel 323 until a new frame is submitted for composition. 324 325 @return \link DisplayError \endlink 326 327 @sa Prepare 328 @sa Commit 329 */ 330 virtual DisplayError Flush() = 0; 331 332 /*! @brief Method to get current state of the display device. 333 334 @param[out] state \link DisplayState \endlink 335 336 @return \link DisplayError \endlink 337 338 @sa SetDisplayState 339 */ 340 virtual DisplayError GetDisplayState(DisplayState *state) = 0; 341 342 /*! @brief Method to get number of configurations(variable properties) supported on the display 343 device. 344 345 @param[out] count Number of modes supported; mode index starts with 0. 346 347 @return \link DisplayError \endlink 348 */ 349 virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count) = 0; 350 351 /*! @brief Method to get configuration for fixed properties of the display device. 352 353 @param[out] fixed_info \link DisplayConfigFixedInfo \endlink 354 355 @return \link DisplayError \endlink 356 */ 357 virtual DisplayError GetConfig(DisplayConfigFixedInfo *fixed_info) = 0; 358 359 /*! @brief Method to get configuration for variable properties of the display device. 360 361 @param[in] index index of the mode 362 @param[out] variable_info \link DisplayConfigVariableInfo \endlink 363 364 @return \link DisplayError \endlink 365 */ 366 virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) = 0; 367 368 /*! @brief Method to get index of active configuration of the display device. 369 370 @param[out] index index of the mode corresponding to variable properties. 371 372 @return \link DisplayError \endlink 373 */ 374 virtual DisplayError GetActiveConfig(uint32_t *index) = 0; 375 376 /*! @brief Method to get VSync event state. Default event state is disabled. 377 378 @param[out] enabled vsync state 379 380 @return \link DisplayError \endlink 381 */ 382 virtual DisplayError GetVSyncState(bool *enabled) = 0; 383 384 /*! @brief Method to set current state of the display device. 385 386 @param[in] state \link DisplayState \endlink 387 388 @return \link DisplayError \endlink 389 390 @sa SetDisplayState 391 */ 392 virtual DisplayError SetDisplayState(DisplayState state) = 0; 393 394 /*! @brief Method to set active configuration for variable properties of the display device. 395 396 @param[in] variable_info \link DisplayConfigVariableInfo \endlink 397 398 @return \link DisplayError \endlink 399 */ 400 virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) = 0; 401 402 /*! @brief Method to set active configuration for variable properties of the display device. 403 404 @param[in] index index of the mode corresponding to variable properties. 405 406 @return \link DisplayError \endlink 407 */ 408 virtual DisplayError SetActiveConfig(uint32_t index) = 0; 409 410 /*! @brief Method to set VSync event state. Default event state is disabled. 411 412 @param[out] enabled vsync state 413 414 @return \link DisplayError \endlink 415 */ 416 virtual DisplayError SetVSyncState(bool enable) = 0; 417 418 /*! @brief Method to set idle timeout value. Idle fallback is disabled with timeout value 0. 419 420 @param[in] active_ms value in milliseconds. 421 422 @return \link void \endlink 423 */ 424 virtual void SetIdleTimeoutMs(uint32_t active_ms) = 0; 425 426 /*! @brief Method to set maximum number of mixer stages for each display. 427 428 @param[in] max_mixer_stages maximum number of mixer stages. 429 430 @return \link DisplayError \endlink 431 */ 432 virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages) = 0; 433 434 /*! @brief Method to control partial update feature for each display. 435 436 @param[in] enable partial update feature control flag 437 @param[out] pending whether the operation is completed or pending for completion 438 439 @return \link DisplayError \endlink 440 */ 441 virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) = 0; 442 443 /*! @brief Method to disable partial update for at least 1 frame. 444 @return \link DisplayError \endlink 445 */ 446 virtual DisplayError DisablePartialUpdateOneFrame() = 0; 447 448 /*! @brief Method to set the mode of the primary display. 449 450 @param[in] mode the new display mode. 451 452 @return \link DisplayError \endlink 453 */ 454 virtual DisplayError SetDisplayMode(uint32_t mode) = 0; 455 456 /*! @brief Method to get the min and max refresh rate of a display. 457 458 @param[out] min and max refresh rate. 459 460 @return \link DisplayError \endlink 461 */ 462 virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, 463 uint32_t *max_refresh_rate) = 0; 464 465 /*! @brief Method to set the refresh rate of a display. 466 467 @param[in] new refresh rate of the display. 468 469 @return \link DisplayError \endlink 470 */ 471 virtual DisplayError SetRefreshRate(uint32_t refresh_rate) = 0; 472 473 /*! @brief Method to query whether scanning is support for the HDMI display. 474 475 @return \link DisplayError \endlink 476 */ 477 virtual bool IsUnderscanSupported() = 0; 478 479 /*! @brief Method to set brightness of the primary display. 480 481 @param[in] level the new backlight level. 482 483 @return \link DisplayError \endlink 484 */ 485 virtual DisplayError SetPanelBrightness(int level) = 0; 486 487 /*! @brief Method to cache brightness of the primary display. 488 489 @param[in] level the new backlight level. 490 491 @return \link DisplayError \endlink 492 */ 493 virtual DisplayError CachePanelBrightness(int level) = 0; 494 495 /*! @brief Method to notify display about change in min HDCP encryption level. 496 497 @param[in] min_enc_level minimum encryption level value. 498 499 @return \link DisplayError \endlink 500 */ 501 virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) = 0; 502 503 /*! @brief Method to route display API requests to color service. 504 505 @param[in] in_payload \link PPDisplayAPIPayload \endlink 506 @param[out] out_payload \link PPDisplayPayload \endlink 507 @param[out] pending_action \link PPPendingParams \endlink 508 509 @return \link DisplayError \endlink 510 */ 511 virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload, 512 PPDisplayAPIPayload *out_payload, 513 PPPendingParams *pending_action) = 0; 514 515 /*! @brief Method to request the number of color modes supported. 516 517 @param[out] mode_count Number of modes 518 519 @return \link DisplayError \endlink 520 */ 521 virtual DisplayError GetColorModeCount(uint32_t *mode_count) = 0; 522 523 /*! @brief Method to request the information of supported color modes. 524 525 @param[inout] mode_count Number of updated modes 526 @param[out] vector of mode strings 527 528 @return \link DisplayError \endlink 529 */ 530 virtual DisplayError GetColorModes(uint32_t *mode_count, 531 std::vector<std::string> *color_modes) = 0; 532 533 /*! @brief Method to request the attributes of color mode. 534 535 @param[in] mode name 536 @param[out] vector of mode attributes 537 538 @return \link DisplayError \endlink 539 */ 540 virtual DisplayError GetColorModeAttr(const std::string &color_mode, 541 AttrVal *attr_map) = 0; 542 543 /*! @brief Method to set the color mode 544 545 @param[in] mode_name Mode name which needs to be set 546 547 @return \link DisplayError \endlink 548 */ 549 virtual DisplayError SetColorMode(const std::string &color_mode) = 0; 550 551 /*! @brief Method to set the color transform 552 553 @param[in] length Mode name which needs to be set 554 @param[in] color_transform 4x4 Matrix for color transform 555 556 @return \link DisplayError \endlink 557 */ 558 virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) = 0; 559 560 /*! @brief Method to get the default color mode. 561 562 @param[out] default mode name 563 564 @return \link DisplayError \endlink 565 */ 566 virtual DisplayError GetDefaultColorMode(std::string *color_mode) = 0; 567 568 /*! @brief Method to request applying default display mode. 569 570 @return \link DisplayError \endlink 571 */ 572 virtual DisplayError ApplyDefaultDisplayMode() = 0; 573 574 /*! @brief Method to set the position of the hw cursor. 575 576 @param[in] x \link x position \endlink 577 @param[in] y \link y position \endlink 578 579 @return \link DisplayError \endlink 580 */ 581 virtual DisplayError SetCursorPosition(int x, int y) = 0; 582 583 /*! @brief Method to get the brightness level of the display 584 585 @param[out] level brightness level 586 587 @return \link DisplayError \endlink 588 */ 589 virtual DisplayError GetPanelBrightness(int *level) = 0; 590 591 /*! @brief Method to set layer mixer resolution. 592 593 @param[in] width layer mixer width 594 @param[in] height layer mixer height 595 596 @return \link DisplayError \endlink 597 */ 598 virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) = 0; 599 600 /*! @brief Method to get layer mixer resolution. 601 602 @param[out] width layer mixer width 603 @param[out] height layer mixer height 604 605 @return \link DisplayError \endlink 606 */ 607 virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height) = 0; 608 609 /*! @brief Method to set frame buffer configuration. 610 611 @param[in] variable_info \link DisplayConfigVariableInfo \endlink 612 613 @return \link DisplayError \endlink 614 */ 615 virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) = 0; 616 617 /*! @brief Method to get frame buffer configuration. 618 619 @param[out] variable_info \link DisplayConfigVariableInfo \endlink 620 621 @return \link DisplayError \endlink 622 */ 623 virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) = 0; 624 625 /*! @brief Method to set detail enhancement data. 626 627 @param[in] de_data \link DisplayDetailEnhancerData \endlink 628 629 @return \link DisplayError \endlink 630 */ 631 virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) = 0; 632 633 /*! @brief Method to get display port information. 634 635 @param[out] port \link DisplayPort \endlink 636 637 @return \link DisplayError \endlink 638 */ 639 virtual DisplayError GetDisplayPort(DisplayPort *port) = 0; 640 641 /*! @brief Method to query whether it is Primrary device. 642 643 @return true if this interface is primary. 644 */ 645 virtual bool IsPrimaryDisplay() = 0; 646 647 /*! @brief Method to toggle composition types handling by SDM. 648 649 @details Client shall call this method to request SDM to enable/disable a specific type of 650 layer composition. If client disables a composition type, SDM will not handle any of the layer 651 composition using the disabled method in a draw cycle. On lack of resources to handle all 652 layers using other enabled composition methods, Prepare() will return an error. 653 654 Request to toggle composition type is applied from subsequent draw cycles. 655 656 Default state of all defined composition types is enabled. 657 658 @param[in] composition_type \link LayerComposition \endlink 659 @param[in] enable \link enable composition type \endlink 660 661 @return \link DisplayError \endlink 662 663 @sa Prepare 664 */ 665 virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0; 666 667 protected: 668 virtual ~DisplayInterface() { } 669}; 670 671} // namespace sdm 672 673#endif // __DISPLAY_INTERFACE_H__ 674 675