update OpenHarmony 2.0 Canary

This commit is contained in:
mamingshuai 2021-06-02 00:06:03 +08:00
parent 34fb37404f
commit 915a42948f
174 changed files with 18062 additions and 61 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
*.tgz filter=lfs diff=lfs merge=lfs -text
*.trp filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.asm filter=lfs diff=lfs merge=lfs -text
*.8svn filter=lfs diff=lfs merge=lfs -text
*.9svn filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text

40
BUILD.gn Normal file
View File

@ -0,0 +1,40 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Install graphic.rc to /system/etc/init/graphic.rc {{{
ohos_prebuilt_etc("graphic.rc") {
source = "graphic.rc"
relative_install_dir = "init"
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Install graphic.rc to /system/etc/init/graphic.rc }}}
group("libsurface") {
public_deps = [ "frameworks/surface:surface" ]
}
group("libvsync_client") {
public_deps = [ "frameworks/vsync:libvsync_client" ]
}
group("libvsync_server") {
public_deps = [ "frameworks/vsync:libvsync_server" ]
}
group("libwms_client") {
public_deps = [ "frameworks/wm:wms_client" ]
}

177
LICENSE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -1,36 +0,0 @@
# graphic_standard
#### Description
Window manager and compositor | 图形窗口合成器
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

728
README.md
View File

@ -1,37 +1,715 @@
# graphic_standard
# Graphics<a name="EN-US_TOPIC_0000001105482134"></a>
#### 介绍
Window manager and compositor | 图形窗口合成器
- [Introduction](#section1333751883213)
- [Directory Structure](#section1882912343)
- [Constraints](#section68982123611)
- [Compilation and Building](#section671864110372)
- [Available APIs](#section197399520386)
- [WindowManager](#section5851104093816)
- [Window](#section3483122273912)
- [SubWindow](#section96481249183913)
- [Surface](#section12366161544010)
- [SurfaceBuffer](#section12001640184711)
- [VsyncHelper](#section1392116294211)
#### 软件架构
软件架构说明
- [Usage](#section18359134910422)
- [Transferring a Producer Surface](#section193464304411)
- [Creating a Producer Surface](#section1276823075112)
- [Producing a SurfaceBuffer](#section614545716513)
- [Consuming a SurfaceBuffer](#section315285412535)
- [Adding Custom Data to a SurfaceBuffer](#section612412125616)
- [Registering a Vsync Callback Listener](#section1148115214576)
- [\#EN-US\_TOPIC\_0000001105482134/section1939493174420](#section1939493174420)
- [Repositories Involved](#section6488145313)
## Introduction<a name="section1333751883213"></a>
The Graphics subsystem provides graphics and window management capabilities, which can be invoked by using Java or JS APIs. It can be used for UI development for all standard-system devices.
The following figure shows the architecture of the Graphics subsystem.
![](figures/graphic.png)
- Surface
Provides APIs for managing the graphics buffer and the efficient and convenient rotation buffer.
- Vsync
Provides APIs for managing registration and response of all vertical sync signals.
- WindowManager
Provides APIs for creating and managing windows.
- WaylandProtocols
Provides the communication protocols between the window manager and synthesizer.
- Compositor
Implements synthesis of layers.
- Renderer
Functions as the back-end rendering module of the synthesizer.
- Wayland protocols
Provides Wayland inter-process communication protocols.
- Shell
Provides multi-window capabilities.
- Input Manger
Functions as the multimodal input module that receives input events.
#### 安装教程
## Directory Structure<a name="section1882912343"></a>
1. xxxx
2. xxxx
3. xxxx
```
foundation/graphic/standard/
├── frameworks # Framework code
│ ├── bootanimation # Boot Animation code
│ ├── surface # Surface code
│ ├── vsync # Vsync code
│ └── wm # WindowManager code
├── interfaces # External APIs
│ ├── innerkits # Native APIs
│ └── kits # JS APIs and NAPIs
└── utils # Utilities
```
#### 使用说明
## Constraints<a name="section68982123611"></a>
1. xxxx
2. xxxx
3. xxxx
- Language version: C++ 11 or later
#### 参与贡献
## Compilation and Building<a name="section671864110372"></a>
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
The dependent APIs include the following:
- graphic\_standard:libwms\_client
- graphic\_standard:libsurface
- graphic\_standard:libvsync\_client
## Available APIs<a name="section197399520386"></a>
### WindowManager<a name="section5851104093816"></a>
<a name="table119mcpsimp"></a>
<table><thead align="left"><tr id="row124mcpsimp"><th class="cellrowborder" valign="top" width="37%" id="mcps1.1.3.1.1"><p id="p126mcpsimp"><a name="p126mcpsimp"></a><a name="p126mcpsimp"></a><strong id="b193946358456"><a name="b193946358456"></a><a name="b193946358456"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="63%" id="mcps1.1.3.1.2"><p id="p129mcpsimp"><a name="p129mcpsimp"></a><a name="p129mcpsimp"></a><strong id="b128701367459"><a name="b128701367459"></a><a name="b128701367459"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row132mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p134mcpsimp"><a name="p134mcpsimp"></a><a name="p134mcpsimp"></a>GetInstance</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p136mcpsimp"><a name="p136mcpsimp"></a><a name="p136mcpsimp"></a>Obtains the pointer to a singleton <strong id="b18411195111456"><a name="b18411195111456"></a><a name="b18411195111456"></a>WindowManager</strong> instance.</p>
</td>
</tr>
<tr id="row137mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p139mcpsimp"><a name="p139mcpsimp"></a><a name="p139mcpsimp"></a>GetMaxWidth</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p141mcpsimp"><a name="p141mcpsimp"></a><a name="p141mcpsimp"></a>Obtains the width of the screen.</p>
</td>
</tr>
<tr id="row142mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p144mcpsimp"><a name="p144mcpsimp"></a><a name="p144mcpsimp"></a>GetMaxHeight</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p146mcpsimp"><a name="p146mcpsimp"></a><a name="p146mcpsimp"></a>Obtains the height of the screen.</p>
</td>
</tr>
<tr id="row147mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p149mcpsimp"><a name="p149mcpsimp"></a><a name="p149mcpsimp"></a>CreateWindow</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p151mcpsimp"><a name="p151mcpsimp"></a><a name="p151mcpsimp"></a>Creates a standard window.</p>
</td>
</tr>
<tr id="row152mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p154mcpsimp"><a name="p154mcpsimp"></a><a name="p154mcpsimp"></a>CreateSubWindow</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p156mcpsimp"><a name="p156mcpsimp"></a><a name="p156mcpsimp"></a>Creates a child window.</p>
</td>
</tr>
<tr id="row157mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p159mcpsimp"><a name="p159mcpsimp"></a><a name="p159mcpsimp"></a>StartShotScreen</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p161mcpsimp"><a name="p161mcpsimp"></a><a name="p161mcpsimp"></a>Takes a screenshot.</p>
</td>
</tr>
<tr id="row162mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p164mcpsimp"><a name="p164mcpsimp"></a><a name="p164mcpsimp"></a>StartShotWindow</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p166mcpsimp"><a name="p166mcpsimp"></a><a name="p166mcpsimp"></a>Captures a window.</p>
</td>
</tr>
<tr id="row167mcpsimp"><td class="cellrowborder" valign="top" width="37%" headers="mcps1.1.3.1.1 "><p id="p169mcpsimp"><a name="p169mcpsimp"></a><a name="p169mcpsimp"></a>SwitchTop</p>
</td>
<td class="cellrowborder" valign="top" width="63%" headers="mcps1.1.3.1.2 "><p id="p171mcpsimp"><a name="p171mcpsimp"></a><a name="p171mcpsimp"></a>Moves the specified window to the top.</p>
</td>
</tr>
</tbody>
</table>
### Window<a name="section3483122273912"></a>
<a name="table173mcpsimp"></a>
<table><thead align="left"><tr id="row178mcpsimp"><th class="cellrowborder" valign="top" width="48%" id="mcps1.1.3.1.1"><p id="p180mcpsimp"><a name="p180mcpsimp"></a><a name="p180mcpsimp"></a><strong id="b1734339115416"><a name="b1734339115416"></a><a name="b1734339115416"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="52%" id="mcps1.1.3.1.2"><p id="p183mcpsimp"><a name="p183mcpsimp"></a><a name="p183mcpsimp"></a><strong id="b660764018548"><a name="b660764018548"></a><a name="b660764018548"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row186mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p188mcpsimp"><a name="p188mcpsimp"></a><a name="p188mcpsimp"></a>Show</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p190mcpsimp"><a name="p190mcpsimp"></a><a name="p190mcpsimp"></a>Displays the current window.</p>
</td>
</tr>
<tr id="row191mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p193mcpsimp"><a name="p193mcpsimp"></a><a name="p193mcpsimp"></a>Hide</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p195mcpsimp"><a name="p195mcpsimp"></a><a name="p195mcpsimp"></a>Hides the current window.</p>
</td>
</tr>
<tr id="row196mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p198mcpsimp"><a name="p198mcpsimp"></a><a name="p198mcpsimp"></a>Move</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p200mcpsimp"><a name="p200mcpsimp"></a><a name="p200mcpsimp"></a>Moves the current window to a specified position.</p>
</td>
</tr>
<tr id="row201mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p203mcpsimp"><a name="p203mcpsimp"></a><a name="p203mcpsimp"></a>SwitchTop</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p205mcpsimp"><a name="p205mcpsimp"></a><a name="p205mcpsimp"></a>Moves the current window to the top.</p>
</td>
</tr>
<tr id="row206mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p208mcpsimp"><a name="p208mcpsimp"></a><a name="p208mcpsimp"></a>ChangeWindowType</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p210mcpsimp"><a name="p210mcpsimp"></a><a name="p210mcpsimp"></a>Changes the type of the current window.</p>
</td>
</tr>
<tr id="row211mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p213mcpsimp"><a name="p213mcpsimp"></a><a name="p213mcpsimp"></a>ReSize</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p215mcpsimp"><a name="p215mcpsimp"></a><a name="p215mcpsimp"></a>Resizes the current window.</p>
</td>
</tr>
<tr id="row216mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p218mcpsimp"><a name="p218mcpsimp"></a><a name="p218mcpsimp"></a>Rotate</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p220mcpsimp"><a name="p220mcpsimp"></a><a name="p220mcpsimp"></a>Rotates the current window.</p>
</td>
</tr>
<tr id="row221mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p223mcpsimp"><a name="p223mcpsimp"></a><a name="p223mcpsimp"></a>RegistPointerButtonCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p225mcpsimp"><a name="p225mcpsimp"></a><a name="p225mcpsimp"></a>Registers the callback for Button events of the mouse.</p>
</td>
</tr>
<tr id="row226mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p228mcpsimp"><a name="p228mcpsimp"></a><a name="p228mcpsimp"></a>RegistPointerEnterCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p230mcpsimp"><a name="p230mcpsimp"></a><a name="p230mcpsimp"></a>Registers the callback for Enter events of the mouse.</p>
</td>
</tr>
<tr id="row231mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p233mcpsimp"><a name="p233mcpsimp"></a><a name="p233mcpsimp"></a>RegistPointerLeaveCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p235mcpsimp"><a name="p235mcpsimp"></a><a name="p235mcpsimp"></a>Registers the callback for Leave events of the mouse.</p>
</td>
</tr>
<tr id="row236mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p238mcpsimp"><a name="p238mcpsimp"></a><a name="p238mcpsimp"></a>RegistPointerMotionCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p240mcpsimp"><a name="p240mcpsimp"></a><a name="p240mcpsimp"></a>Registers the callback for Motion events of the mouse.</p>
</td>
</tr>
<tr id="row241mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p243mcpsimp"><a name="p243mcpsimp"></a><a name="p243mcpsimp"></a>RegistPointerAxisDiscreteCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p245mcpsimp"><a name="p245mcpsimp"></a><a name="p245mcpsimp"></a>Registers the callback for AxisDiscrete events of the mouse.</p>
</td>
</tr>
<tr id="row246mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p248mcpsimp"><a name="p248mcpsimp"></a><a name="p248mcpsimp"></a>RegistPointerAxisSourceCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p250mcpsimp"><a name="p250mcpsimp"></a><a name="p250mcpsimp"></a>Registers the callback for AxisSource events of the mouse.</p>
</td>
</tr>
<tr id="row251mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p253mcpsimp"><a name="p253mcpsimp"></a><a name="p253mcpsimp"></a>RegistPointerAxisStopCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p255mcpsimp"><a name="p255mcpsimp"></a><a name="p255mcpsimp"></a>Registers the callback for AxisStop events of the mouse.</p>
</td>
</tr>
<tr id="row256mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p258mcpsimp"><a name="p258mcpsimp"></a><a name="p258mcpsimp"></a>RegistPointerAxisCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p260mcpsimp"><a name="p260mcpsimp"></a><a name="p260mcpsimp"></a>Registers the callback for Axis events of the mouse.</p>
</td>
</tr>
<tr id="row261mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p263mcpsimp"><a name="p263mcpsimp"></a><a name="p263mcpsimp"></a>RegistTouchUpCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p265mcpsimp"><a name="p265mcpsimp"></a><a name="p265mcpsimp"></a>Registers the callback for TouchUp events.</p>
</td>
</tr>
<tr id="row266mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p268mcpsimp"><a name="p268mcpsimp"></a><a name="p268mcpsimp"></a>RegistTouchDownCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p270mcpsimp"><a name="p270mcpsimp"></a><a name="p270mcpsimp"></a>Registers the callback for TouchDown events.</p>
</td>
</tr>
<tr id="row271mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p273mcpsimp"><a name="p273mcpsimp"></a><a name="p273mcpsimp"></a>RegistTouchEmotionCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p275mcpsimp"><a name="p275mcpsimp"></a><a name="p275mcpsimp"></a>Registers the callback for TouchEmotion events.</p>
</td>
</tr>
<tr id="row276mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p278mcpsimp"><a name="p278mcpsimp"></a><a name="p278mcpsimp"></a>RegistTouchFrameCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p280mcpsimp"><a name="p280mcpsimp"></a><a name="p280mcpsimp"></a>Registers the callback for TouchFrame events.</p>
</td>
</tr>
<tr id="row281mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p283mcpsimp"><a name="p283mcpsimp"></a><a name="p283mcpsimp"></a>RegistTouchCancelCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p285mcpsimp"><a name="p285mcpsimp"></a><a name="p285mcpsimp"></a>Registers the callback for TouchCancel events.</p>
</td>
</tr>
<tr id="row286mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p288mcpsimp"><a name="p288mcpsimp"></a><a name="p288mcpsimp"></a>RegistTouchShapeCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p290mcpsimp"><a name="p290mcpsimp"></a><a name="p290mcpsimp"></a>Registers the callback for TouchShape events.</p>
</td>
</tr>
<tr id="row291mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p293mcpsimp"><a name="p293mcpsimp"></a><a name="p293mcpsimp"></a>RegistTouchOrientationCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p295mcpsimp"><a name="p295mcpsimp"></a><a name="p295mcpsimp"></a>Registers the callback for TouchOrientation events.</p>
</td>
</tr>
<tr id="row296mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p298mcpsimp"><a name="p298mcpsimp"></a><a name="p298mcpsimp"></a>RegistKeyboardKeyCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p300mcpsimp"><a name="p300mcpsimp"></a><a name="p300mcpsimp"></a>Registers the callback for Key events of the keyboard.</p>
</td>
</tr>
<tr id="row301mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p303mcpsimp"><a name="p303mcpsimp"></a><a name="p303mcpsimp"></a>RegistKeyboardKeyMapCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p305mcpsimp"><a name="p305mcpsimp"></a><a name="p305mcpsimp"></a>Registers the callback for KeyMap events of the keyboard.</p>
</td>
</tr>
<tr id="row306mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p308mcpsimp"><a name="p308mcpsimp"></a><a name="p308mcpsimp"></a>RegistKeyboardLeaveCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p310mcpsimp"><a name="p310mcpsimp"></a><a name="p310mcpsimp"></a>Registers the callback for Leave events of the keyboard.</p>
</td>
</tr>
<tr id="row311mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p313mcpsimp"><a name="p313mcpsimp"></a><a name="p313mcpsimp"></a>RegistKeyboardEnterCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p315mcpsimp"><a name="p315mcpsimp"></a><a name="p315mcpsimp"></a>Registers the callback for Enter events of the keyboard.</p>
</td>
</tr>
<tr id="row316mcpsimp"><td class="cellrowborder" valign="top" width="48%" headers="mcps1.1.3.1.1 "><p id="p318mcpsimp"><a name="p318mcpsimp"></a><a name="p318mcpsimp"></a>RegistKeyboardRepeatInfoCb</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.1.3.1.2 "><p id="p320mcpsimp"><a name="p320mcpsimp"></a><a name="p320mcpsimp"></a>Registers the callback for RepeatInfo events of the keyboard.</p>
</td>
</tr>
</tbody>
</table>
### SubWindow<a name="section96481249183913"></a>
<a name="table322mcpsimp"></a>
<table><thead align="left"><tr id="row327mcpsimp"><th class="cellrowborder" valign="top" width="49%" id="mcps1.1.3.1.1"><p id="p329mcpsimp"><a name="p329mcpsimp"></a><a name="p329mcpsimp"></a><strong id="b131086571302"><a name="b131086571302"></a><a name="b131086571302"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="51%" id="mcps1.1.3.1.2"><p id="p332mcpsimp"><a name="p332mcpsimp"></a><a name="p332mcpsimp"></a><strong id="b041313581403"><a name="b041313581403"></a><a name="b041313581403"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row335mcpsimp"><td class="cellrowborder" valign="top" width="49%" headers="mcps1.1.3.1.1 "><p id="p337mcpsimp"><a name="p337mcpsimp"></a><a name="p337mcpsimp"></a>Move</p>
</td>
<td class="cellrowborder" valign="top" width="51%" headers="mcps1.1.3.1.2 "><p id="p339mcpsimp"><a name="p339mcpsimp"></a><a name="p339mcpsimp"></a>Moves the current child window.</p>
</td>
</tr>
<tr id="row340mcpsimp"><td class="cellrowborder" valign="top" width="49%" headers="mcps1.1.3.1.1 "><p id="p342mcpsimp"><a name="p342mcpsimp"></a><a name="p342mcpsimp"></a>SetSubWindowSize</p>
</td>
<td class="cellrowborder" valign="top" width="51%" headers="mcps1.1.3.1.2 "><p id="p344mcpsimp"><a name="p344mcpsimp"></a><a name="p344mcpsimp"></a>Sets the size of the current child window.</p>
</td>
</tr>
</tbody>
</table>
### Surface<a name="section12366161544010"></a>
<a name="table346mcpsimp"></a>
<table><thead align="left"><tr id="row351mcpsimp"><th class="cellrowborder" valign="top" width="41%" id="mcps1.1.3.1.1"><p id="p353mcpsimp"><a name="p353mcpsimp"></a><a name="p353mcpsimp"></a><strong id="b8875439216"><a name="b8875439216"></a><a name="b8875439216"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="59%" id="mcps1.1.3.1.2"><p id="p356mcpsimp"><a name="p356mcpsimp"></a><a name="p356mcpsimp"></a><strong id="b14608174222"><a name="b14608174222"></a><a name="b14608174222"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row359mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p361mcpsimp"><a name="p361mcpsimp"></a><a name="p361mcpsimp"></a>CreateSurfaceAsConsumer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p363mcpsimp"><a name="p363mcpsimp"></a><a name="p363mcpsimp"></a>Creates a surface for the buffer consumer.</p>
</td>
</tr>
<tr id="row364mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p366mcpsimp"><a name="p366mcpsimp"></a><a name="p366mcpsimp"></a>CreateSurfaceAsProducer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p368mcpsimp"><a name="p368mcpsimp"></a><a name="p368mcpsimp"></a>Creates a surface for the buffer producer. Only production-related APIs can be used.</p>
</td>
</tr>
<tr id="row369mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p371mcpsimp"><a name="p371mcpsimp"></a><a name="p371mcpsimp"></a>GetProducer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p373mcpsimp"><a name="p373mcpsimp"></a><a name="p373mcpsimp"></a>Obtains an internal <strong id="b1982865713319"><a name="b1982865713319"></a><a name="b1982865713319"></a>IBufferProducer</strong> object of <strong id="b14235152710419"><a name="b14235152710419"></a><a name="b14235152710419"></a>Surface</strong>.</p>
</td>
</tr>
<tr id="row374mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p376mcpsimp"><a name="p376mcpsimp"></a><a name="p376mcpsimp"></a>RequestBuffer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p378mcpsimp"><a name="p378mcpsimp"></a><a name="p378mcpsimp"></a>Requests a <strong id="b17591192851510"><a name="b17591192851510"></a><a name="b17591192851510"></a>SurfaceBuffer</strong> object to be produced.</p>
</td>
</tr>
<tr id="row379mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p381mcpsimp"><a name="p381mcpsimp"></a><a name="p381mcpsimp"></a>CancelBuffer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p383mcpsimp"><a name="p383mcpsimp"></a><a name="p383mcpsimp"></a>Cancels a <strong id="b11160135061513"><a name="b11160135061513"></a><a name="b11160135061513"></a>SurfaceBuffer</strong> object to be produced.</p>
</td>
</tr>
<tr id="row384mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p386mcpsimp"><a name="p386mcpsimp"></a><a name="p386mcpsimp"></a>FlushBuffer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p388mcpsimp"><a name="p388mcpsimp"></a><a name="p388mcpsimp"></a>Flushes a produced <strong id="b19478235151718"><a name="b19478235151718"></a><a name="b19478235151718"></a>SurfaceBuffer</strong> object with certain information.</p>
</td>
</tr>
<tr id="row389mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p391mcpsimp"><a name="p391mcpsimp"></a><a name="p391mcpsimp"></a>AcquireBuffer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p393mcpsimp"><a name="p393mcpsimp"></a><a name="p393mcpsimp"></a>Requests a <strong id="b4187111419210"><a name="b4187111419210"></a><a name="b4187111419210"></a>SurfaceBuffer</strong> object to be consumed.</p>
</td>
</tr>
<tr id="row394mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p396mcpsimp"><a name="p396mcpsimp"></a><a name="p396mcpsimp"></a>ReleaseBuffer</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p398mcpsimp"><a name="p398mcpsimp"></a><a name="p398mcpsimp"></a>Returns a consumed <strong id="b626752116217"><a name="b626752116217"></a><a name="b626752116217"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row399mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p401mcpsimp"><a name="p401mcpsimp"></a><a name="p401mcpsimp"></a>GetQueueSize</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p403mcpsimp"><a name="p403mcpsimp"></a><a name="p403mcpsimp"></a>Obtains the number of concurrent buffers.</p>
</td>
</tr>
<tr id="row404mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p406mcpsimp"><a name="p406mcpsimp"></a><a name="p406mcpsimp"></a>SetQueueSize</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p408mcpsimp"><a name="p408mcpsimp"></a><a name="p408mcpsimp"></a>Sets the number of concurrent buffers.</p>
</td>
</tr>
<tr id="row409mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p411mcpsimp"><a name="p411mcpsimp"></a><a name="p411mcpsimp"></a>SetDefaultWidthAndHeight</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p413mcpsimp"><a name="p413mcpsimp"></a><a name="p413mcpsimp"></a>Sets the default width and height.</p>
</td>
</tr>
<tr id="row414mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p416mcpsimp"><a name="p416mcpsimp"></a><a name="p416mcpsimp"></a>GetDefaultWidth</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p418mcpsimp"><a name="p418mcpsimp"></a><a name="p418mcpsimp"></a>Obtains the default width.</p>
</td>
</tr>
<tr id="row419mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p421mcpsimp"><a name="p421mcpsimp"></a><a name="p421mcpsimp"></a>GetDefaultHeight</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p423mcpsimp"><a name="p423mcpsimp"></a><a name="p423mcpsimp"></a>Obtains the default height.</p>
</td>
</tr>
<tr id="row424mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p426mcpsimp"><a name="p426mcpsimp"></a><a name="p426mcpsimp"></a>SetUserData</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p428mcpsimp"><a name="p428mcpsimp"></a><a name="p428mcpsimp"></a>Stores string data, which will not be transferred through IPC.</p>
</td>
</tr>
<tr id="row429mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p431mcpsimp"><a name="p431mcpsimp"></a><a name="p431mcpsimp"></a>GetUserData</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p433mcpsimp"><a name="p433mcpsimp"></a><a name="p433mcpsimp"></a>Obtains string data.</p>
</td>
</tr>
<tr id="row434mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p436mcpsimp"><a name="p436mcpsimp"></a><a name="p436mcpsimp"></a>RegisterConsumerListener</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p438mcpsimp"><a name="p438mcpsimp"></a><a name="p438mcpsimp"></a>Registers a consumer listener to listen for buffer flush events.</p>
</td>
</tr>
<tr id="row439mcpsimp"><td class="cellrowborder" valign="top" width="41%" headers="mcps1.1.3.1.1 "><p id="p441mcpsimp"><a name="p441mcpsimp"></a><a name="p441mcpsimp"></a>UnregisterConsumerListener</p>
</td>
<td class="cellrowborder" valign="top" width="59%" headers="mcps1.1.3.1.2 "><p id="p443mcpsimp"><a name="p443mcpsimp"></a><a name="p443mcpsimp"></a>Unregiseters a consumer listener.</p>
</td>
</tr>
</tbody>
</table>
### SurfaceBuffer<a name="section12001640184711"></a>
<a name="table445mcpsimp"></a>
<table><thead align="left"><tr id="row450mcpsimp"><th class="cellrowborder" valign="top" width="32%" id="mcps1.1.3.1.1"><p id="p452mcpsimp"><a name="p452mcpsimp"></a><a name="p452mcpsimp"></a><strong id="b1560753920274"><a name="b1560753920274"></a><a name="b1560753920274"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="68%" id="mcps1.1.3.1.2"><p id="p455mcpsimp"><a name="p455mcpsimp"></a><a name="p455mcpsimp"></a><strong id="b010044116274"><a name="b010044116274"></a><a name="b010044116274"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row458mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p460mcpsimp"><a name="p460mcpsimp"></a><a name="p460mcpsimp"></a>GetBufferHandle</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p462mcpsimp"><a name="p462mcpsimp"></a><a name="p462mcpsimp"></a>Obtains the <strong id="b15990748192713"><a name="b15990748192713"></a><a name="b15990748192713"></a>BufferHandle</strong> pointer to the <strong id="b10706250132715"><a name="b10706250132715"></a><a name="b10706250132715"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row463mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p465mcpsimp"><a name="p465mcpsimp"></a><a name="p465mcpsimp"></a>GetWidth</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p467mcpsimp"><a name="p467mcpsimp"></a><a name="p467mcpsimp"></a>Obtains the width of the <strong id="b109605268315"><a name="b109605268315"></a><a name="b109605268315"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row468mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p470mcpsimp"><a name="p470mcpsimp"></a><a name="p470mcpsimp"></a>GetHeight</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p472mcpsimp"><a name="p472mcpsimp"></a><a name="p472mcpsimp"></a>Obtains the height of the <strong id="b142632918311"><a name="b142632918311"></a><a name="b142632918311"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row473mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p475mcpsimp"><a name="p475mcpsimp"></a><a name="p475mcpsimp"></a>GetFormat</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p477mcpsimp"><a name="p477mcpsimp"></a><a name="p477mcpsimp"></a>Obtains the color format of the <strong id="b11157143123112"><a name="b11157143123112"></a><a name="b11157143123112"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row478mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p480mcpsimp"><a name="p480mcpsimp"></a><a name="p480mcpsimp"></a>GetUsage</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p482mcpsimp"><a name="p482mcpsimp"></a><a name="p482mcpsimp"></a>Obtains the usage of the <strong id="b15685153383114"><a name="b15685153383114"></a><a name="b15685153383114"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row483mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p485mcpsimp"><a name="p485mcpsimp"></a><a name="p485mcpsimp"></a>GetPhyAddr</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p487mcpsimp"><a name="p487mcpsimp"></a><a name="p487mcpsimp"></a>Obtains the physical address of the <strong id="b1569003614310"><a name="b1569003614310"></a><a name="b1569003614310"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row488mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p490mcpsimp"><a name="p490mcpsimp"></a><a name="p490mcpsimp"></a>GetKey</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p492mcpsimp"><a name="p492mcpsimp"></a><a name="p492mcpsimp"></a>Obtains the key of the <strong id="b1679393910314"><a name="b1679393910314"></a><a name="b1679393910314"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row493mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p495mcpsimp"><a name="p495mcpsimp"></a><a name="p495mcpsimp"></a>GetVirAddr</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p497mcpsimp"><a name="p497mcpsimp"></a><a name="p497mcpsimp"></a>Obtains the virtual address of the <strong id="b56714253110"><a name="b56714253110"></a><a name="b56714253110"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row498mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p500mcpsimp"><a name="p500mcpsimp"></a><a name="p500mcpsimp"></a>GetSize</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p502mcpsimp"><a name="p502mcpsimp"></a><a name="p502mcpsimp"></a>Obtains the size of the <strong id="b12547184533112"><a name="b12547184533112"></a><a name="b12547184533112"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row503mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p505mcpsimp"><a name="p505mcpsimp"></a><a name="p505mcpsimp"></a>SetInt32</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p507mcpsimp"><a name="p507mcpsimp"></a><a name="p507mcpsimp"></a>Sets the 32-bit integer for the <strong id="b284244873112"><a name="b284244873112"></a><a name="b284244873112"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row508mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p510mcpsimp"><a name="p510mcpsimp"></a><a name="p510mcpsimp"></a>GetInt32</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p512mcpsimp"><a name="p512mcpsimp"></a><a name="p512mcpsimp"></a>Obtains the 32-bit integer for the <strong id="b11398105163116"><a name="b11398105163116"></a><a name="b11398105163116"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row513mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p515mcpsimp"><a name="p515mcpsimp"></a><a name="p515mcpsimp"></a>SetInt64</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p517mcpsimp"><a name="p517mcpsimp"></a><a name="p517mcpsimp"></a>Sets the 64-bit integer for the <strong id="b19859155463116"><a name="b19859155463116"></a><a name="b19859155463116"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
<tr id="row518mcpsimp"><td class="cellrowborder" valign="top" width="32%" headers="mcps1.1.3.1.1 "><p id="p520mcpsimp"><a name="p520mcpsimp"></a><a name="p520mcpsimp"></a>GetInt64</p>
</td>
<td class="cellrowborder" valign="top" width="68%" headers="mcps1.1.3.1.2 "><p id="p522mcpsimp"><a name="p522mcpsimp"></a><a name="p522mcpsimp"></a>Obtains the 64-bit integer for the <strong id="b753775763118"><a name="b753775763118"></a><a name="b753775763118"></a>SurfaceBuffer</strong> object.</p>
</td>
</tr>
</tbody>
</table>
### VsyncHelper<a name="section1392116294211"></a>
<a name="table524mcpsimp"></a>
<table><thead align="left"><tr id="row529mcpsimp"><th class="cellrowborder" valign="top" width="38%" id="mcps1.1.3.1.1"><p id="p531mcpsimp"><a name="p531mcpsimp"></a><a name="p531mcpsimp"></a><strong id="b133428253019"><a name="b133428253019"></a><a name="b133428253019"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="62%" id="mcps1.1.3.1.2"><p id="p534mcpsimp"><a name="p534mcpsimp"></a><a name="p534mcpsimp"></a><strong id="b16934026309"><a name="b16934026309"></a><a name="b16934026309"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row537mcpsimp"><td class="cellrowborder" valign="top" width="38%" headers="mcps1.1.3.1.1 "><p id="p539mcpsimp"><a name="p539mcpsimp"></a><a name="p539mcpsimp"></a>Current</p>
</td>
<td class="cellrowborder" valign="top" width="62%" headers="mcps1.1.3.1.2 "><p id="p541mcpsimp"><a name="p541mcpsimp"></a><a name="p541mcpsimp"></a>Obtains the <strong id="b25453472308"><a name="b25453472308"></a><a name="b25453472308"></a>VsyncHelper</strong> object of the current runner.</p>
</td>
</tr>
<tr id="row542mcpsimp"><td class="cellrowborder" valign="top" width="38%" headers="mcps1.1.3.1.1 "><p id="p544mcpsimp"><a name="p544mcpsimp"></a><a name="p544mcpsimp"></a>VsyncHelper</p>
</td>
<td class="cellrowborder" valign="top" width="62%" headers="mcps1.1.3.1.2 "><p id="p546mcpsimp"><a name="p546mcpsimp"></a><a name="p546mcpsimp"></a>Constructs a <strong id="b157281123143212"><a name="b157281123143212"></a><a name="b157281123143212"></a>VsyncHelper</strong> object using an <strong id="b1650443412326"><a name="b1650443412326"></a><a name="b1650443412326"></a>EventHandler</strong> object.</p>
</td>
</tr>
<tr id="row547mcpsimp"><td class="cellrowborder" valign="top" width="38%" headers="mcps1.1.3.1.1 "><p id="p549mcpsimp"><a name="p549mcpsimp"></a><a name="p549mcpsimp"></a>RequestFrameCallback</p>
</td>
<td class="cellrowborder" valign="top" width="62%" headers="mcps1.1.3.1.2 "><p id="p551mcpsimp"><a name="p551mcpsimp"></a><a name="p551mcpsimp"></a>Registers a frame callback.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section18359134910422"></a>
### Transferring a Producer Surface<a name="section193464304411"></a>
1. Named service
- Service registration:
```
// Obtain a consumer surface.
sptr<Surface> surface = Surface::CreateSurfaceAsConsumer();
// Extract the producer object.
sptr<IBufferProducer> producer = surface->GetProducer();
// Register the service.
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sm->AddSystemAbility(IPC_SA_ID, producer->AsObject());
```
- Construction of a producer surface:
```
// Obtain a producer object.
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> robj = sm->GetSystemAbility(IPC_SA_ID);
// Construct a surface.
sptr<IBufferProducer> bp = iface_cast<IBufferProducer>(robj);
sptr<Surface> surface = Surface::CreateSurfaceAsProducer(bp);
```
#### 特技
2. Anonymous service
- Sending of a surface:
```
// Obtain a consumer surface.
sptr<Surface> surface = CreateSurfaceAsConsumer();
// Extract the producer object.
sptr<IRemoteObject> producer = surface->GetProducer();
// Return the producer object to the client.
parcel.WriteRemoteObject(producer);
```
### Creating a Producer Surface<a name="section1276823075112"></a>
```
// Obtain a producer object.
sptr<IRemoteObject> remoteObject = parcel.ReadRemoteObject();
// Construct a surface.
sptr<IBufferProducer> bp = iface_cast<IBufferProducer>(robj);
sptr<Surface> surface = Surface::CreateSurfaceAsProducer(bp);
```
### Producing a SurfaceBuffer<a name="section614545716513"></a>
```
// Prerequisite: a producer surface
BufferRequestConfig requestConfig = {
.width = 1920, // Screen width
.height = 1080, // Screen height
.strideAlignment = 8, // Stride alignment byte
.format = PIXEL_FMT_RGBA_8888, // Color format
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, // Usage
.timeout = 0, // Delay
};
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, requestConfig);
if (ret != SURFACE_ERROR_OK) {
// failed
}
BufferFlushConfig flushConfig = {
.damage = { // Redrawing buffer zone
.x = 0, // Horizontal coordinate of the start point
.y = 0, // Vertical coordinate of the start point
.w = buffer->GetWidth(), // Width of the buffer zone
.h = buffer->GetHeight(), // Height of the buffer zone
},
.timestamp = 0 // Time displayed to consumers. Value 0 indicates the current time.
};
ret = surface->FlushBuffer(buffer, -1, flushConfig);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### Consuming a SurfaceBuffer<a name="section315285412535"></a>
```
// Prerequisite: a consumer surface
class TestConsumerListener : public IBufferConsumerListener {
public:
void OnBufferAvailable() override {
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
SurfaceError ret = surface->AcquireBuffer(buffer, flushFence, timestamp, damage);
if (ret != SURFACE_ERROR_OK) {
// failed
}
// ...
ret = surface->ReleaseBuffer(buffer, -1);
if (ret != SURFACE_ERROR_OK) {
// failed
}
}
};
sptr<IBufferConsumerListener> listener = new TestConsumerListener();
SurfaceError ret = surface->RegisterConsumerListener(listener);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### Adding Custom Data to a SurfaceBuffer<a name="section612412125616"></a>
```
sptr<SurfaceBuffer> buffer;
SurfaceError ret = buffer->SetInt32(1, 3);
if (ret != SURFACE_ERROR_OK) {
// failed
}
int32_t val;
ret = buffer->GetInt32(1, val);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### Registering a Vsync Callback Listener<a name="section1148115214576"></a>
1. Construct a **VsyncHelper** object using **handler**.
```
auto runner = AppExecFwk::EventRunner::Create(true);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
auto helper = new VsyncHelper(handler);
runner->Run();
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = nullptr,
.callback_ = [](int64_t timestamp, void* userdata) {
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
if (ret != VSYNC_ERROR_OK) {
// failed
}
```
2. Use **Current** in **handler**.
```
auto runner = AppExecFwk::EventRunner::Create(true);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask([]() {
auto helper = VsyncHelper::Current();
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = nullptr,
.callback_ = [](int64_t timestamp, void* userdata) {
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
if (ret != VSYNC_ERROR_OK) {
// failed
}
});
runner->Run();
```
## Repositories Involved<a name="section6488145313"></a>
Graphics subsystem
**graphic\_standard**
ace\_ace\_engine
aafwk\_L2
multimedia\_media\_standard
multimedia\_camera\_standard
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

361
README_zh.md Normal file
View File

@ -0,0 +1,361 @@
# graphic_standard
- [简介](#简介)
- [目录](#目录)
- [约束](#约束)
- [编译构建](#编译构建)
- [接口说明](#接口说明)
- [使用说明](#使用说明)
- [相关仓](#相关仓)
## 简介
**Graphic子系统** 提供了图形接口能力和窗口管理接口能力,
其主要的结构如下图所示:
![Graphic子系统架构图](./figures/graphic.png)
- **Surface**
图形缓冲区管理接口,负责管理图形缓冲区和高效便捷的轮转缓冲区。
- **Vsync**
垂直同步信号管理接口,负责管理所有垂直同步信号注册和响应。
- **WindowManager**
窗口管理器接口,负责创建和管理窗口。
- **WaylandProtocols**
窗口管理器和合成器的通信协议。
- **Compositor**
合成器,负责合成各个图层。
- **Renderer**
合成器的后端渲染模块。
- **Wayland protocols**
Wayland 进程间通信协议
- **Shell**
提供多窗口能力
- **Input Manger**
多模输入模块,负责接收事件输入
## 目录
```
foundation/graphic/standard/
├── frameworks # 框架代码目录
│ ├── bootanimation # 开机动画目录
│   ├── surface # Surface代码
│   ├── vsync # Vsync代码
│   └── wm # WindowManager代码
├── interfaces # 对外接口存放目录
│   ├── innerkits # native接口存放目录
│   └── kits # js/napi接口存放目录
└── utils # 小部件存放目录
```
## 约束
- 语言版本
- C++11或以上
## 编译构建
可以依赖的接口有:
- graphic_standard:libwms_client
- graphic_standard:libsurface
- graphic_standard:libvsync_client
## 接口说明
### WindowManager
| 接口名 | 职责 |
|-----------------|-----------------------------|
| GetInstance | 获取WindowManager的单例指针 |
| GetMaxWidth | 获取当前屏幕宽度 |
| GetMaxHeight | 获取当前屏幕高度 |
| CreateWindow | 创建一个标准窗口 |
| CreateSubWindow | 创建一个子窗口 |
| StartShotScreen | 截屏操作 |
| StartShotWindow | 截取窗口操作 |
| SwitchTop | 将指定窗口调整至最上层显示 |
### Window
| 接口名 | 职责 |
|-----------------------------|------------------------------|
| Show | 显示当前窗口 |
| Hide | 隐藏当前窗口 |
| Move | 移动当前窗口至指定位置 |
| SwitchTop | 将当前窗口调整到最上层显示 |
| ChangeWindowType | 更改当前窗口类型 |
| ReSize | 调整当前窗口至指定大小 |
| Rotate | 旋转当前窗口 |
| RegistPointerButtonCb | 注册鼠标Button事件回调 |
| RegistPointerEnterCb | 注册鼠标Enter事件回调 |
| RegistPointerLeaveCb | 注册鼠标Leave事件回调 |
| RegistPointerMotionCb | 注册鼠标Motion事件回调 |
| RegistPointerAxisDiscreteCb | 注册鼠标AxisDiscrete事件回调 |
| RegistPointerAxisSourceCb | 注册鼠标AxisSource事件回调 |
| RegistPointerAxisStopCb | 注册鼠标AxisStop事件回调 |
| RegistPointerAxisCb | 注册鼠标Axis事件回调 |
| RegistTouchUpCb | 注册TouchUp事件回调 |
| RegistTouchDownCb | 注册TouchDown事件回调 |
| RegistTouchEmotionCb | 注册TouchEmotion事件回调 |
| RegistTouchFrameCb | 注册TouchFrame事件回调 |
| RegistTouchCancelCb | 注册TouchCancel事件回调 |
| RegistTouchShapeCb | 注册TouchShape事件回调 |
| RegistTouchOrientationCb | 注册TouchOrientation事件回调 |
| RegistKeyboardKeyCb | 注册键盘Key事件回调 |
| RegistKeyboardKeyMapCb | 注册键盘KeyMap事件回调 |
| RegistKeyboardLeaveCb | 注册键盘Leave事件回调 |
| RegistKeyboardEnterCb | 注册键盘Enter事件回调 |
| RegistKeyboardRepeatInfoCb | 注册键盘RepeatInfo事件回调 |
### SubWindow
| 接口名 | 职责 |
|------------------|--------------------|
| Move | 移动当前子窗口 |
| SetSubWindowSize | 调整当前子窗口位置 |
### Surface
| 接口名 | 职责 |
|----------------------------|-------------------------------------------------------------------|
| CreateSurfaceAsConsumer | Buffer的消费者来使用该函数创建一个Surface |
| CreateSurfaceAsProducer | Buffer的生产者使用该函数创建一个Surface只能使用与生产相关的接口 |
| GetProducer | 获得一个Surface内部的IBufferProducer对象 |
| RequestBuffer | 请求一个待生产的SurfaceBuffer对象 |
| CancelBuffer | 取消、归还一个待生产的SurfaceBuffer对象 |
| FlushBuffer | 归还一个生产好的SurfaceBuffer对象并携带一些信息 |
| AcquireBuffer | 请求一个待消费的SurfaceBuffer对象 |
| ReleaseBuffer | 归还一个已消费的SurfaceBuffer对象 |
| GetQueueSize | 获得当前同时能并存buffer的数量 |
| SetQueueSize | 设置当前同时能并存buffer的数量 |
| SetDefaultWidthAndHeight | 设置默认宽和高 |
| GetDefaultWidth | 获得默认宽度 |
| GetDefaultHeight | 获得默认高度 |
| SetUserData | 存贮字符串数据不随着IPC传递 |
| GetUserData | 取出字符串数据 |
| RegisterConsumerListener | 注册一个消费监听器监听Buffer的Flush事件 |
| UnregisterConsumerListener | 取消监听 |
### SurfaceBuffer
| 接口名 | 职责 |
|-----------------|-------------------------------------|
| GetBufferHandle | 获得SurfaceBuffer的BufferHandle指针 |
| GetWidth | 获得SurfaceBuffer的宽度 |
| GetHeight | 获得SurfaceBuffer的高度 |
| GetFormat | 获得SurfaceBuffer的颜色格式 |
| GetUsage | 获得SurfaceBuffer的用途 |
| GetPhyAddr | 获得SurfaceBuffer的物理地址 |
| GetKey | 获得SurfaceBuffer的key |
| GetVirAddr | 获得SurfaceBuffer的虚拟地址 |
| GetSize | 获得SurfaceBuffer的文件句柄 |
| SetInt32 | 获得SurfaceBuffer的缓冲区大小 |
| GetInt32 | 设置SurfaceBuffer的32位整数 |
| SetInt64 | 获得SurfaceBuffer的32位整数 |
| GetInt64 | 设置SurfaceBuffer的64位整数 |
### VsyncHelper
| 接口名 | 职责 |
|----------------------|-----------------------------------|
| Current | 获取当前runner对应的VsyncHelper |
| VsyncHelper | 用EventHandler对象构造VsyncHelper |
| RequestFrameCallback | 注册一个帧回调 |
## 使用说明
### 具名服务-传递一个生产型Surface
#### 注册
```cpp
// 拿到一个消费型Surface
sptr<Surface> surface = Surface::CreateSurfaceAsConsumer();
// 拿出里面的生产者对象
sptr<IBufferProducer> producer = surface->GetProducer();
// 注册服务
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sm->AddSystemAbility(IPC_SA_ID, producer->AsObject());
```
#### 客户端获得生产型Surface
```cpp
// 获得远程对象
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> robj = sm->GetSystemAbility(IPC_SA_ID);
// 构造Surface
sptr<IBufferProducer> bp = iface_cast<IBufferProducer>(robj);
sptr<Surface> surface = Surface::CreateSurfaceAsProducer(bp);
```
### 匿名服务-传递一个生产型Surface
场景: 在一次IPC过程中
#### 发送
```cpp
// 拿到一个消费型Surface
sptr<Surface> surface = CreateSurfaceAsConsumer();
// 拿出里面的生产者对象
sptr<IRemoteObject> producer = surface->GetProducer();
// 返回给客户端
parcel.WriteRemoteObject(producer);
```
#### 接受并获得生产型Surface
```cpp
// 获得远程对象
sptr<IRemoteObject> remoteObject = parcel.ReadRemoteObject();
// 构造Surface
sptr<IBufferProducer> bp = iface_cast<IBufferProducer>(robj);
sptr<Surface> surface = Surface::CreateSurfaceAsProducer(bp);
```
### 生产一个SurfaceBuffer
条件: 一个生产型Surface
```cpp
BufferRequestConfig requestConfig = {
.width = 1920, // 屏幕宽度
.height = 1080, // 屏幕高度
.strideAlignment = 8, // stride对齐字节
.format = PIXEL_FMT_RGBA_8888, // 颜色格式
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, // 用法
.timeout = 0, // 时延
};
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, requestConfig);
if (ret != SURFACE_ERROR_OK) {
// failed
}
BufferFlushConfig flushConfig = {
.damage = { // 重绘区域
.x = 0, // 起点横坐标
.y = 0, // 起点纵坐标
.w = buffer->GetWidth(), // 区域宽度
.h = buffer->GetHeight(), // 区域高度
},
.timestamp = 0 // 给消费者看的时间0为使用当前时间
};
ret = surface->FlushBuffer(buffer, -1, flushConfig);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### 消费一个SurfaceBuffer
条件: 一个消费型Surface
```cpp
class TestConsumerListener : public IBufferConsumerListener {
public:
void OnBufferAvailable() override {
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
SurfaceError ret = surface->AcquireBuffer(buffer, flushFence, timestamp, damage);
if (ret != SURFACE_ERROR_OK) {
// failed
}
// ...
ret = surface->ReleaseBuffer(buffer, -1);
if (ret != SURFACE_ERROR_OK) {
// failed
}
}
};
sptr<IBufferConsumerListener> listener = new TestConsumerListener();
SurfaceError ret = surface->RegisterConsumerListener(listener);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### 给SurfaceBuffer带上自定义数据
```cpp
sptr<SurfaceBuffer> buffer;
SurfaceError ret = buffer->SetInt32(1, 3);
if (ret != SURFACE_ERROR_OK) {
// failed
}
int32_t val;
ret = buffer->GetInt32(1, val);
if (ret != SURFACE_ERROR_OK) {
// failed
}
```
### 注册一个Vsync回调事件
#### 用handler构造VsyncHelper
```cpp
auto runner = AppExecFwk::EventRunner::Create(true);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
auto helper = new VsyncHelper(handler);
runner->Run();
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = nullptr,
.callback_ = [](int64_t timestamp, void* userdata) {
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
if (ret != VSYNC_ERROR_OK) {
// failed
}
```
#### 在handler里用Current
```cpp
auto runner = AppExecFwk::EventRunner::Create(true);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask([]() {
auto helper = VsyncHelper::Current();
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = nullptr,
.callback_ = [](int64_t timestamp, void* userdata) {
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
if (ret != VSYNC_ERROR_OK) {
// failed
}
});
runner->Run();
```
## 相关仓
- **graphic_standard**
- ace_ace_engine
- aafwk_standard
- multimedia_media_standard
- multimedia_camera_standard

BIN
figures/graphic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,61 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Build bootanimation {{{
config("bootanimation_config") {
visibility = [ ":*" ]
include_dirs = [ "include" ]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
ohos_executable("bootanimation") {
install_enable = true
sources = [
"src/main.cpp",
"src/raw_parser.cpp",
"src/util.cpp",
]
configs = [ ":bootanimation_config" ]
deps = [
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
"//foundation/graphic/standard:libvsync_client",
"//foundation/graphic/standard:libwms_client",
"//third_party/zlib:libz",
]
external_deps = ["ipc:ipc_core"]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build bootanimation }}}
## Install data/bootanimation.raw to /system/etc/bootanimation.raw {{{
ohos_prebuilt_etc("bootanimation.raw") {
source = "data/bootanimation.raw"
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Install data/bootanimation.raw to /system/etc//bootanimation.raw }}}

Binary file not shown.

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_BOOTANIMATION_INCLUDE_RAW_PARSER_H
#define FRAMEWORKS_BOOTANIMATION_INCLUDE_RAW_PARSER_H
#include <memory>
#include <string>
#include <vector>
#include <refbase.h>
namespace OHOS {
enum {
ZLIBINFO_TYPE_NONE,
ZLIBINFO_TYPE_RAW,
ZLIBINFO_TYPE_COMPRESSED,
};
struct ZlibInfo {
uint32_t type;
uint32_t offset;
uint32_t length;
uint32_t clen;
uint8_t *mem;
};
// parse bootanimation raw data
class RawParser : public RefBase {
public:
static sptr<RawParser> GetInstance();
// 0 for success
int32_t Parse(std::string &filename);
// 0 for success
int32_t GetData(uint32_t count, uint8_t* &pData, uint32_t &offset, uint32_t &length);
// 0 for success
int32_t Uncompress(std::unique_ptr<uint8_t[]> &dst, uint32_t dstlen, uint8_t *cmem, uint32_t clen);
protected:
// 0 for success
int32_t ReadFile(std::string &filename);
private:
static sptr<RawParser> instance;
RawParser();
virtual ~RawParser();
std::unique_ptr<uint8_t[]> compressed = nullptr;
uint32_t clength = 0;
std::vector<struct ZlibInfo> infos;
std::unique_ptr<uint8_t[]> uncompressed = nullptr;
static constexpr int32_t magicHeaderLength = 8;
};
} // namespace OHOS
#endif // FRAMEWORKS_BOOTANIMATION_INCLUDE_RAW_PARSER_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_BOOTANIMATION_INCLUDE_UTIL_H
#define FRAMEWORKS_BOOTANIMATION_INCLUDE_UTIL_H
#include <cstdint>
#include <functional>
#include <hilog/log.h>
namespace OHOS {
#define LOG(fmt, ...) ::OHOS::HiviewDFX::HiLog::Info( \
::OHOS::HiviewDFX::HiLogLabel {LOG_CORE, 0, "BootAnimation"}, \
"%{public}s: " fmt, __func__, ##__VA_ARGS__)
int64_t GetNowTime();
void PostTask(std::function<void()> func, uint32_t delayTime = 0);
void RequestSync(void (*syncFunc)(int64_t, void*), void *data);
} // namespace OHOS
#endif // FRAMEWORKS_BOOTANIMATION_INCLUDE_UTIL_H

View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <securec.h>
#include <unistd.h>
#include <display_type.h>
#include <vsync_helper.h>
#include <window_manager.h>
#include "raw_parser.h"
#include "util.h"
using namespace OHOS;
namespace {
namespace {
constexpr uint32_t POSTTIME = 12 * 1000;
constexpr uint32_t PRETIME = 3 * 1000;
}
int32_t DoDraw(uint8_t *addr, uint32_t width, uint32_t height, uint32_t count)
{
constexpr uint32_t stride = 4;
int32_t addrSize = width * height * stride;
static auto frame = std::make_unique<uint8_t[]>(addrSize);
static uint32_t last = -1;
int64_t start = GetNowTime();
uint8_t *data = nullptr;
uint32_t length;
uint32_t offset;
if (RawParser::GetInstance()->GetData(count, data, offset, length)) {
return -1;
}
if (last != count && length > 0) {
memcpy_s(frame.get() + offset, addrSize - offset, data, length);
}
memcpy_s(addr, addrSize, frame.get(), addrSize);
last = count;
LOG("GetData time: %{public}lld, data: %{public}p, length: %{public}d", GetNowTime() - start, data, length);
return 0;
}
void Draw(Window *window)
{
sptr<Surface> surface = window->GetSurface();
if (surface == nullptr) {
LOG("surface is nullptr");
return;
}
do {
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
BufferRequestConfig config;
window->GetRequestConfig(config);
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
if (ret == SURFACE_ERROR_NO_BUFFER) {
break;
}
if (ret) {
LOG("RequestBuffer failed: %{public}s", SurfaceErrorStr(ret).c_str());
break;
}
if (buffer == nullptr) {
break;
}
static uint32_t count = 0;
auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
while (true) {
int32_t drawRet = DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), count);
if (drawRet && count == 0) {
exit(1);
}
if (drawRet) {
count--;
continue;
}
break;
}
BufferFlushConfig flushConfig = {
.damage = {
.w = buffer->GetWidth(),
.h = buffer->GetHeight(),
},
};
ret = surface->FlushBuffer(buffer, -1, flushConfig);
LOG("Sync %{public}d %{public}s", count, SurfaceErrorStr(ret).c_str());
fflush(stdout);
count++;
} while (false);
}
void DoubleSync(int64_t time, void *data)
{
static int32_t count = 0;
if (count % 2 == 0) {
Draw(reinterpret_cast<Window *>(data));
}
count++;
RequestSync(DoubleSync, data);
}
void Main()
{
const int32_t width = WindowManager::GetInstance()->GetMaxWidth();
const int32_t height = WindowManager::GetInstance()->GetMaxHeight();
WindowConfig config = {
.width = width,
.height = height,
.pos_x = 0,
.pos_y = 0,
.format = PIXEL_FMT_RGBA_8888,
.type = WINDOW_TYPE_NORMAL,
};
static std::unique_ptr<Window> window = WindowManager::GetInstance()->CreateWindow(&config);
if (window == nullptr) {
LOG("window is nullptr");
} else {
window->Move(0, 0);
window->ReSize(width, height);
window->SwitchTop();
auto onWindowCreate = [](uint32_t pid) {
constexpr uint32_t stringLength = 32;
char filename[stringLength];
(void)snprintf_s(filename,
sizeof(filename), sizeof(filename) - 1, "/proc/%d/cmdline", pid);
auto fp = fopen(filename, "r");
if (fp == nullptr) {
return;
}
char cmdline[stringLength] = {};
fread(cmdline, sizeof(char), stringLength, fp);
fclose(fp);
if (strcmp(cmdline, "com.ohos.systemui") == 0 ||
strcmp(cmdline, "com.ohos.launcher") == 0) {
LOG("exiting");
exit(0);
}
};
window->RegistOnWindowCreateCb(onWindowCreate);
DoubleSync(0, window.get());
}
PostTask([]() { LOG(""); exit(0); }, PRETIME + POSTTIME);
}
}
int main(int argc, const char *argv[])
{
int64_t start = GetNowTime();
std::string filename = "/system/etc/bootanimation.raw";
if (RawParser::GetInstance()->Parse(filename)) {
return -1;
}
LOG("time: %{public}lld", GetNowTime() - start);
auto runner = AppExecFwk::EventRunner::Create(false);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask(Main);
runner->Run();
return 0;
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "raw_parser.h"
#include <cstdio>
#include <mutex>
#include <securec.h>
#include <zlib.h>
#include "util.h"
namespace OHOS {
sptr<RawParser> RawParser::instance = nullptr;
sptr<RawParser> RawParser::GetInstance()
{
if (instance == nullptr) {
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr) {
instance = new RawParser();
}
}
return instance;
}
RawParser::RawParser() : infos()
{
}
RawParser::~RawParser()
{
}
int32_t RawParser::Parse(std::string &filename)
{
int32_t ret = ReadFile(filename);
if (ret) {
LOG("ReadFile failed");
return ret;
}
auto magic = reinterpret_cast<char *>(&compressed[0]);
if (strstr(magic, "RAW.diff") == nullptr) {
constexpr uint32_t magicHeaderStringLength = magicHeaderLength + 2;
char fileMagic[magicHeaderStringLength];
memcpy_s(fileMagic, sizeof(fileMagic) - 1, magic, magicHeaderLength);
LOG("file magic is wrong, %{public}s", fileMagic);
return -1;
}
struct HeaderInfo {
uint32_t type;
uint32_t offset;
uint32_t length;
uint32_t clen;
uint8_t mem[0];
};
struct HeaderInfo *info = reinterpret_cast<struct HeaderInfo *>(&compressed[magicHeaderLength]);
uint32_t ipos = reinterpret_cast<uint8_t *>(info) - reinterpret_cast<uint8_t *>(magic);
while (ipos < clength) {
LOG("[%{public}d, %{public}d], type: %{public}d, "
"offset: %{public}d, length: %{public}d, clen: %{public}d, mem: %{public}p",
infos.size() + 1, ipos, info->type, info->offset, info->length, info->clen, info->mem);
if (info->clen < 0) {
LOG("info->clen less then 0");
return -1;
}
struct ZlibInfo zi = {
.type = info->type,
.offset = info->offset,
.length = info->length,
.clen = info->clen,
.mem = info->mem,
};
infos.push_back(zi);
// for BUS_ADRALN
constexpr uint32_t memalign = 4;
uint32_t align = info->clen - info->clen / memalign * memalign;
if (align) {
align = memalign - align;
}
info = reinterpret_cast<struct HeaderInfo *>(info->mem + info->clen + align);
ipos = reinterpret_cast<uint8_t *>(info) - reinterpret_cast<uint8_t *>(magic);
}
if (infos.empty()) {
LOG("file have no zip");
return -1;
}
return 0;
}
int32_t RawParser::GetData(uint32_t count, uint8_t* &pData, uint32_t &offset, uint32_t &length)
{
if (count >= infos.size()) {
return -1;
}
offset = infos[count].offset;
length = infos[count].length;
if (length == 0) {
pData = nullptr;
return 0;
}
uncompressed = std::make_unique<uint8_t[]>(length);
int32_t ret = Uncompress(uncompressed, length, infos[count].mem, infos[count].clen);
if (ret) {
return -1;
}
pData = uncompressed.get();
return 0;
}
int32_t RawParser::ReadFile(std::string &filename)
{
FILE *fp = fopen(filename.c_str(), "rb");
if (fp == nullptr) {
LOG("open %{public}s failed, %{public}d", filename.c_str(), errno);
return -1;
}
fseek(fp, 0, SEEK_END);
clength = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (clength < magicHeaderLength) {
LOG("%{public}s is too small", filename.c_str());
fclose(fp);
return -1;
}
compressed = std::make_unique<uint8_t[]>(clength);
fread(&compressed[0], sizeof(uint8_t), clength, fp);
fclose(fp);
LOG("compressed: %{public}p, length: %{public}d", compressed.get(), clength);
return 0;
}
int32_t RawParser::Uncompress(std::unique_ptr<uint8_t[]> &dst, uint32_t dstlen, uint8_t *cmem, uint32_t clen)
{
unsigned long ulength = dstlen;
auto ret = uncompress(dst.get(), &ulength, cmem, clen);
if (ret) {
LOG("uncompress failed with %{public}d", ret);
}
return ret;
}
} // namespace OHOS

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "util.h"
#include <ctime>
#include <vsync_helper.h>
namespace OHOS {
int64_t GetNowTime()
{
struct timeval start = {};
gettimeofday(&start, nullptr);
constexpr uint32_t secToUsec = 1000 * 1000;
return static_cast<int64_t>(start.tv_sec) * secToUsec + start.tv_usec;
}
void PostTask(std::function<void()> func, uint32_t delayTime)
{
auto handler = AppExecFwk::EventHandler::Current();
if (handler) {
handler->PostTask(func, delayTime);
}
}
void RequestSync(void (*syncFunc)(int64_t, void*), void *data)
{
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = data,
.callback_ = syncFunc,
};
VsyncError ret = VsyncHelper::Current()->RequestFrameCallback(cb);
if (ret) {
LOG("RequestFrameCallback inner %{public}d\n", ret);
}
}
} // namespace OHOS

77
frameworks/surface/BUILD.gn Executable file
View File

@ -0,0 +1,77 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Build surface.so {{{
config("surface_config") {
visibility = [ ":*" ]
include_dirs = [ "include" ]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("surface_public_config") {
include_dirs =
[ "//foundation/graphic/standard/interfaces/innerkits/surface" ]
}
ohos_shared_library("surface") {
sources = [
"src/buffer_client_producer.cpp",
"src/buffer_manager.cpp",
"src/buffer_queue.cpp",
"src/buffer_queue_consumer.cpp",
"src/buffer_queue_producer.cpp",
"src/buffer_utils.cpp",
"src/consumer_surface.cpp",
"src/producer_surface.cpp",
"src/surface.cpp",
"src/surface_buffer_impl.cpp",
]
configs = [ ":surface_config" ]
public_configs = [
":surface_public_config",
"//utils/native/base:utils_config",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
public_deps = [
"//foundation/graphic/standard/prebuilts/librarys/display_gralloc:libdisplay_gralloc",
"//foundation/graphic/standard/utils:buffer_handle",
"//utils/native/base:utils",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build surface.so }}}
group("test") {
testonly = true
deps = [ "test:test" ]
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_CLIENT_PRODUCER_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_CLIENT_PRODUCER_H
#include <map>
#include <vector>
#include <iremote_proxy.h>
#include <iremote_object.h>
#include <ibuffer_producer.h>
#include "surface_buffer_impl.h"
namespace OHOS {
class BufferClientProducer : public IRemoteProxy<IBufferProducer> {
public:
BufferClientProducer(const sptr<IRemoteObject>& impl);
virtual ~BufferClientProducer();
SurfaceError RequestBuffer(int32_t& sequence, sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config,
std::vector<int32_t>& deletingBuffers) override;
SurfaceError CancelBuffer(int32_t sequence) override;
SurfaceError FlushBuffer(int32_t sequence,
int32_t fence, BufferFlushConfig& config) override;
uint32_t GetQueueSize() override;
SurfaceError SetQueueSize(uint32_t queueSize) override;
int32_t GetDefaultWidth() override;
int32_t GetDefaultHeight() override;
SurfaceError CleanCache() override;
private:
static inline BrokerDelegator<BufferClientProducer> delegator_;
};
}; // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_CLIENT_PRODUCER_H

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_LOG_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_LOG_H
#include <hilog/log.h>
namespace OHOS {
#define _B_FMT(color) "\033[" color "m"
#ifdef __aarch64__
#define BPUBI64 "%{public}ld"
#define BPUBSize "%{public}lu"
#define BPUBU64 "%{public}lu"
#else
#define BPUBI64 "%{public}lld"
#define BPUBSize "%{public}u"
#define BPUBU64 "%{public}llu"
#endif
#define _B_RESET ";0"
#define _B_BOLD ";1"
#define _B_UNDERLINE ";4"
#define _B_REVERSE ";7"
#define _B_FG_BLACK ";30"
#define _B_FG_RED ";31"
#define _B_FG_GREEN ";32"
#define _B_FG_YELLOW ";33"
#define _B_FG_BLUE ";34"
#define _B_FG_PURPLE ";35"
#define _B_FG_CYAN ";36"
#define _B_FG_WHITE ";37"
#define _B_DCOLOR _B_FG_WHITE
#define _B_ICOLOR _B_FG_CYAN
#define _B_WCOLOR _B_FG_YELLOW
#define _B_ECOLOR _B_FG_RED _B_BOLD
#define _B_DFUNC HiviewDFX::HiLog::Debug
#define _B_IFUNC HiviewDFX::HiLog::Info
#define _B_WFUNC HiviewDFX::HiLog::Warn
#define _B_EFUNC HiviewDFX::HiLog::Error
#define _B_CPRINTF(func, color, fmt, ...) \
func(LABEL, _B_FMT(color) "<%{public}d>" fmt _B_FMT(_B_RESET), __LINE__, ##__VA_ARGS__)
#define BLOGD(fmt, ...) _B_CPRINTF(_B_DFUNC, _B_DCOLOR, " DEBUG " fmt, ##__VA_ARGS__)
#define BLOGI(fmt, ...) _B_CPRINTF(_B_IFUNC, _B_ICOLOR, fmt, ##__VA_ARGS__)
#define BLOGW(fmt, ...) _B_CPRINTF(_B_WFUNC, _B_WCOLOR, fmt, ##__VA_ARGS__)
#define BLOGE(fmt, ...) _B_CPRINTF(_B_EFUNC, _B_ECOLOR, fmt, ##__VA_ARGS__)
#define _B_FUNC __func__
#define BLOGFD(fmt, ...) BLOGD("%{public}s: " fmt, _B_FUNC, ##__VA_ARGS__)
#define BLOGFI(fmt, ...) BLOGI("%{public}s: " fmt, _B_FUNC, ##__VA_ARGS__)
#define BLOGFW(fmt, ...) BLOGW("%{public}s: " fmt, _B_FUNC, ##__VA_ARGS__)
#define BLOGFE(fmt, ...) BLOGE("%{public}s: " fmt, _B_FUNC, ##__VA_ARGS__)
#define BLOG_SUCCESS(fmt, ...) BLOGFI("Success, Way: " fmt, ##__VA_ARGS__)
#define BLOG_SUCCESS_ID(id, fmt, ...) BLOGFI("Success [%{public}d], Way: " fmt, id, ##__VA_ARGS__)
#define BLOG_INVALID(fmt, ...) BLOGFW("Invalid, " fmt, ##__VA_ARGS__)
#define BLOG_FAILURE(fmt, ...) BLOGFE("Failure, Reason: " fmt, ##__VA_ARGS__)
#define BLOG_FAILURE_RET(ret) \
do { \
BLOG_FAILURE("%{public}s", SurfaceErrorStr(ret).c_str()); \
return ret; \
} while (0)
#define BLOG_FAILURE_API(api, ret) \
BLOG_FAILURE(#api " failed, then %{public}s", SurfaceErrorStr(ret).c_str())
#define BLOG_FAILURE_ID(id, fmt, ...) BLOGFE("Failure [%{public}d], Reason: " fmt, id, ##__VA_ARGS__)
#define BLOG_FAILURE_ID_RET(id, ret) \
do { \
BLOG_FAILURE_ID(id, "%{public}s", SurfaceErrorStr(ret).c_str()); \
return ret; \
} while (0)
#define BLOG_FAILURE_ID_API(id, api, ret) \
BLOG_FAILURE_ID(id, #api " failed, then %{public}s", SurfaceErrorStr(ret).c_str())
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_LOG_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_MANAGER_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_MANAGER_H
#include <surface_type.h>
#include "surface_buffer_impl.h"
#include <display_gralloc.h>
namespace OHOS {
class BufferManager {
public:
static BufferManager* GetInstance()
{
return &instance_;
}
SurfaceError Init();
SurfaceError Alloc(BufferRequestConfig& config, sptr<SurfaceBufferImpl>& buffer);
SurfaceError Map(sptr<SurfaceBufferImpl>& buffer);
SurfaceError Unmap(sptr<SurfaceBufferImpl>& buffer);
SurfaceError FlushCache(sptr<SurfaceBufferImpl>& buffer);
SurfaceError InvalidateCache(sptr<SurfaceBufferImpl>& buffer);
SurfaceError Free(sptr<SurfaceBufferImpl>& buffer);
private:
static BufferManager instance_;
GrallocFuncs* grallocFuncs_;
BufferManager() : grallocFuncs_(nullptr) {}
~BufferManager();
};
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_MANAGER_H

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H
#include <map>
#include <list>
#include <vector>
#include <mutex>
#include <surface_type.h>
#include <ibuffer_consumer_listener.h>
#include "surface_buffer_impl.h"
namespace OHOS {
enum BufferState {
BUFFER_STATE_RELEASED,
BUFFER_STATE_REQUESTED,
BUFFER_STATE_FLUSHED,
BUFFER_STATE_ACQUIRED,
};
typedef struct {
sptr<SurfaceBufferImpl> buffer;
BufferState state;
bool isDeleting;
BufferRequestConfig config;
int32_t fence;
int64_t timestamp;
Rect damage;
} BufferElement;
class BufferQueue : public RefBase {
public:
BufferQueue();
virtual ~BufferQueue();
SurfaceError Init();
SurfaceError RequestBuffer(int32_t& sequence, sptr<SurfaceBufferImpl>& buffer,
int32_t& fence, BufferRequestConfig& config,
std::vector<int32_t>& deletingBuffers);
SurfaceError CancelBuffer(int32_t sequence);
SurfaceError FlushBuffer(int32_t sequence, int32_t fence, BufferFlushConfig& config);
SurfaceError AcquireBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage);
SurfaceError ReleaseBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t fence);
uint32_t GetQueueSize();
SurfaceError SetQueueSize(uint32_t queueSize);
SurfaceError RegisterConsumerListener(sptr<IBufferConsumerListener>& listener);
SurfaceError UnregisterConsumerListener();
SurfaceError SetDefaultWidthAndHeight(int32_t width, int32_t height);
int32_t GetDefaultWidth();
int32_t GetDefaultHeight();
SurfaceError CleanCache();
private:
SurfaceError AllocBuffer(sptr<SurfaceBufferImpl>& buffer, BufferRequestConfig& config);
SurfaceError FreeBuffer(sptr<SurfaceBufferImpl>& buffer);
void DeleteBufferInCache(int sequence);
uint32_t GetUsedSize();
void DeleteBuffers(int32_t count);
SurfaceError PopFromFreeList(sptr<SurfaceBufferImpl>& buffer, BufferRequestConfig& config);
SurfaceError PopFromDirtyList(sptr<SurfaceBufferImpl>& buffer);
SurfaceError CheckRequestConfig(BufferRequestConfig& config);
SurfaceError CheckFlushConfig(BufferFlushConfig& config);
int32_t defaultWidth = 0;
int32_t defaultHeight = 0;
uint32_t queueSize_;
std::list<int32_t> freeList_;
std::list<int32_t> dirtyList_;
std::list<int32_t> deletingList_;
std::map<int32_t, BufferElement> bufferQueueCache_;
sptr<IBufferConsumerListener> listener_;
std::mutex mutex_;
};
}; // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_CONSUMER_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_CONSUMER_H
#include <refbase.h>
#include <surface_type.h>
#include "surface_buffer_impl.h"
#include "buffer_queue.h"
namespace OHOS {
class BufferQueueConsumer : public RefBase {
public:
BufferQueueConsumer(sptr<BufferQueue>& bufferQueue);
virtual ~BufferQueueConsumer();
SurfaceError AcquireBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage);
SurfaceError ReleaseBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t fence);
SurfaceError RegisterConsumerListener(sptr<IBufferConsumerListener>& listener);
SurfaceError UnregisterConsumerListener();
SurfaceError SetDefaultWidthAndHeight(int32_t width, int32_t height);
private:
sptr<BufferQueue> bufferQueue_;
};
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_CONSUMER_H

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_PRODUCER_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_PRODUCER_H
#include <vector>
#include <mutex>
#include <refbase.h>
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
#include <surface_type.h>
#include <ibuffer_producer.h>
#include "buffer_queue.h"
namespace OHOS {
enum BufferQueueProducerState {
BUFFER_QUEUE_PRODUCER_STATE_NORMAL,
BUFFER_QUEUE_PRODUCER_STATE_EXITING,
};
class BufferQueueProducer : public IRemoteStub<IBufferProducer> {
public:
BufferQueueProducer(sptr<BufferQueue>& bufferQueue);
virtual ~BufferQueueProducer();
virtual int OnRemoteRequest(uint32_t code, MessageParcel& arguments,
MessageParcel& reply, MessageOption& option) override;
SurfaceError RequestBuffer(int32_t& sequence, sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config,
std::vector<int32_t>& deletingBuffers) override;
SurfaceError CancelBuffer(int32_t sequence) override;
SurfaceError FlushBuffer(int32_t sequence,
int32_t fence, BufferFlushConfig& config) override;
uint32_t GetQueueSize() override;
SurfaceError SetQueueSize(uint32_t queueSize) override;
int32_t GetDefaultWidth() override;
int32_t GetDefaultHeight() override;
SurfaceError CleanCache() override;
private:
int RequestBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int CancelBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int FlushBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int GetQueueSizeInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int SetQueueSizeInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int GetDefaultWidthInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int GetDefaultHeightInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
int CleanCacheInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option);
using BufferQueueProducerFunc = int (BufferQueueProducer::*)(MessageParcel& arguments,
MessageParcel& reply, MessageOption& option);
std::map<uint32_t, BufferQueueProducerFunc> memberFuncMap_;
sptr<BufferQueue> bufferQueue_;
};
}; // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_QUEUE_PRODUCER_H

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_BUFFER_UTILS_H
#define FRAMEWORKS_SURFACE_INCLUDE_BUFFER_UTILS_H
#include <errno.h>
#include <message_parcel.h>
#include <surface_type.h>
#include "surface_buffer_impl.h"
namespace OHOS {
void ReadFence(MessageParcel& parcel, int32_t& fence);
void WriteFence(MessageParcel& parcel, int32_t fence);
void ReadRequestConfig(MessageParcel& parcel, BufferRequestConfig& config);
void WriteRequestConfig(MessageParcel& parcel, BufferRequestConfig const & config);
void ReadFlushConfig(MessageParcel& parcel, BufferFlushConfig& config);
void WriteFlushConfig(MessageParcel& parcel, BufferFlushConfig const & config);
void ReadSurfaceBufferImpl(MessageParcel& parcel,
int32_t& sequence, sptr<SurfaceBufferImpl>& bufferImpl);
void WriteSurfaceBufferImpl(MessageParcel& parcel,
int32_t sequence, sptr<SurfaceBufferImpl> const & bufferImpl);
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_BUFFER_UTILS_H

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_CONSUMER_SURFACE_H
#define FRAMEWORKS_SURFACE_INCLUDE_CONSUMER_SURFACE_H
#include <map>
#include <string>
#include <surface.h>
#include "buffer_queue.h"
#include "buffer_queue_producer.h"
#include "buffer_queue_consumer.h"
namespace OHOS {
enum SurfaceState {
SURFACE_STATE_NORMAL,
SURFACE_STATE_EXITING,
};
class ConsumerSurface : public Surface {
public:
ConsumerSurface();
virtual ~ConsumerSurface();
SurfaceError Init();
sptr<IBufferProducer> GetProducer() override;
SurfaceError RequestBuffer(sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config) override;
SurfaceError CancelBuffer(sptr<SurfaceBuffer>& buffer) override;
SurfaceError FlushBuffer(sptr<SurfaceBuffer>& buffer,
int32_t fence, BufferFlushConfig& config) override;
SurfaceError AcquireBuffer(sptr<SurfaceBuffer>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage) override;
SurfaceError ReleaseBuffer(sptr<SurfaceBuffer>& buffer, int32_t fence) override;
uint32_t GetQueueSize() override;
SurfaceError SetQueueSize(uint32_t queueSize) override;
SurfaceError SetDefaultWidthAndHeight(int32_t width, int32_t height) override;
int32_t GetDefaultWidth() override;
int32_t GetDefaultHeight() override;
SurfaceError SetUserData(const std::string& key, const std::string& val) override;
std::string GetUserData(const std::string& key) override;
SurfaceError RegisterConsumerListener(sptr<IBufferConsumerListener>& listener) override;
SurfaceError UnregisterConsumerListener() override;
SurfaceError CleanCache() override;
private:
std::map<std::string, std::string> userData_;
sptr<BufferQueueProducer> producer_;
sptr<BufferQueueConsumer> consumer_;
};
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_CONSUMER_SURFACE_H

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_PRODUCER_SURFACE_H
#define FRAMEWORKS_SURFACE_INCLUDE_PRODUCER_SURFACE_H
#include <map>
#include <string>
#include <surface.h>
#include <ibuffer_producer.h>
#include "buffer_queue.h"
#include "buffer_queue_consumer.h"
#include "surface_buffer_impl.h"
namespace OHOS {
class ProducerSurface : public Surface {
public:
ProducerSurface(sptr<IBufferProducer>& producer);
virtual ~ProducerSurface();
SurfaceError Init();
sptr<IBufferProducer> GetProducer() override;
SurfaceError RequestBuffer(sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config) override;
SurfaceError CancelBuffer(sptr<SurfaceBuffer>& buffer) override;
SurfaceError FlushBuffer(sptr<SurfaceBuffer>& buffer,
int32_t fence, BufferFlushConfig& config) override;
SurfaceError AcquireBuffer(sptr<SurfaceBuffer>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage) override;
SurfaceError ReleaseBuffer(sptr<SurfaceBuffer>& buffer, int32_t fence) override;
uint32_t GetQueueSize() override;
SurfaceError SetQueueSize(uint32_t queueSize) override;
SurfaceError SetDefaultWidthAndHeight(int32_t width, int32_t height) override;
int32_t GetDefaultWidth() override;
int32_t GetDefaultHeight() override;
SurfaceError SetUserData(const std::string& key, const std::string& val) override;
std::string GetUserData(const std::string& key) override;
SurfaceError RegisterConsumerListener(sptr<IBufferConsumerListener>& listener) override;
SurfaceError UnregisterConsumerListener() override;
SurfaceError CleanCache() override;
private:
bool IsRemote();
std::map<int32_t, sptr<SurfaceBufferImpl>> bufferProducerCache_;
std::map<std::string, std::string> userData_;
sptr<IBufferProducer> producer_;
};
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_PRODUCER_SURFACE_H

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_INCLUDE_SURFACE_BUFFER_IMPL_H
#define FRAMEWORKS_SURFACE_INCLUDE_SURFACE_BUFFER_IMPL_H
#include <map>
#include <surface_buffer.h>
#include <buffer_handle_parcel.h>
namespace OHOS {
enum ExtraDataType {
EXTRA_DATA_TYPE_MIN,
EXTRA_DATA_TYPE_INT32,
EXTRA_DATA_TYPE_INT64,
EXTRA_DATA_TYPE_MAX,
};
typedef struct {
BufferHandle* handle_;
int32_t sequenceNumber;
} SurfaceBufferData;
typedef struct {
void* value;
uint32_t size;
ExtraDataType type;
} ExtraData;
class MessageParcel;
class SurfaceBufferImpl : public SurfaceBuffer {
public:
SurfaceBufferImpl();
SurfaceBufferImpl(int seqNum);
virtual ~SurfaceBufferImpl();
static SurfaceBufferImpl* FromBase(sptr<SurfaceBuffer>& buffer);
BufferHandle* GetBufferHandle() const override;
int32_t GetWidth() const override;
int32_t GetHeight() const override;
int32_t GetFormat() const override;
int64_t GetUsage() const override;
uint64_t GetPhyAddr() const override;
int32_t GetKey() const override;
void* GetVirAddr() const override;
int32_t GetFileDescriptor() const override;
uint32_t GetSize() const override;
int32_t GetSeqNum();
SurfaceError SetInt32(uint32_t key, int32_t val) override;
SurfaceError GetInt32(uint32_t key, int32_t& val) override;
SurfaceError SetInt64(uint32_t key, int64_t val) override;
SurfaceError GetInt64(uint32_t key, int64_t& val) override;
void SetBufferHandle(BufferHandle* handle);
BufferHandle* GetBufferHandle();
void WriteToMessageParcel(MessageParcel& parcel);
SurfaceBufferData bufferData_;
private:
SurfaceError SetData(uint32_t key, ExtraData data);
SurfaceError GetData(uint32_t key, ExtraData& data);
std::map<uint32_t, ExtraData> extraDatas_;
};
} // namespace OHOS
#endif // FRAMEWORKS_SURFACE_INCLUDE_SURFACE_BUFFER_IMPL_H

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_client_producer.h"
#include "buffer_log.h"
#include "buffer_manager.h"
#include "buffer_utils.h"
#define DEFINE_MESSAGE_VARIABLES(arg, ret, opt, LOGE) \
MessageOption opt; \
MessageParcel arg; \
MessageParcel ret; \
if (!arg.WriteInterfaceToken(GetDescriptor())) { \
LOGE("write interface token failed"); \
}
#define SEND_REQUEST(COMMAND, arguments, reply, option) \
do { \
int32_t ret = Remote()->SendRequest(COMMAND, arguments, reply, option); \
if (ret != ERR_NONE) { \
BLOG_FAILURE("SendRequest return %{public}d", ret); \
return SURFACE_ERROR_BINDER_ERROR; \
} \
} while (0)
#define SEND_REQUEST_WITH_SEQ(COMMAND, arguments, reply, option, sequence) \
do { \
int32_t ret = Remote()->SendRequest(COMMAND, arguments, reply, option); \
if (ret != ERR_NONE) { \
BLOG_FAILURE_ID(sequence, "SendRequest return %{public}d", ret); \
return SURFACE_ERROR_BINDER_ERROR; \
} \
} while (0)
#define CHECK_RETVAL_WITH_SEQ(reply, sequence) \
do { \
int32_t ret = reply.ReadInt32(); \
if (ret != SURFACE_ERROR_OK) { \
BLOG_FAILURE_ID(sequence, "Remote return %{public}d", ret); \
return (SurfaceError)ret; \
} \
} while (0)
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "BufferClientProducer" };
}
BufferClientProducer::BufferClientProducer(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IBufferProducer>(impl)
{
BLOGFD("");
}
BufferClientProducer::~BufferClientProducer()
{
BLOGFD("");
}
SurfaceError BufferClientProducer::RequestBuffer(int32_t& sequence, sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config,
std::vector<int32_t>& deletingBuffers)
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
WriteRequestConfig(arguments, config);
SEND_REQUEST_WITH_SEQ(BUFFER_PRODUCER_REQUEST_BUFFER, arguments, reply, option, sequence);
CHECK_RETVAL_WITH_SEQ(reply, sequence);
ReadFence(reply, fence);
reply.ReadInt32Vector(&deletingBuffers);
sptr<SurfaceBufferImpl> bufferImpl;
ReadSurfaceBufferImpl(reply, sequence, bufferImpl);
buffer = bufferImpl;
return SURFACE_ERROR_OK;
}
SurfaceError BufferClientProducer::CancelBuffer(int32_t sequence)
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
arguments.WriteInt32(sequence);
SEND_REQUEST_WITH_SEQ(BUFFER_PRODUCER_CANCEL_BUFFER, arguments, reply, option, sequence);
CHECK_RETVAL_WITH_SEQ(reply, sequence);
return SURFACE_ERROR_OK;
}
SurfaceError BufferClientProducer::FlushBuffer(int32_t sequence,
int32_t fence, BufferFlushConfig& config)
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
arguments.WriteInt32(sequence);
WriteFence(arguments, fence);
WriteFlushConfig(arguments, config);
SEND_REQUEST_WITH_SEQ(BUFFER_PRODUCER_FLUSH_BUFFER, arguments, reply, option, sequence);
CHECK_RETVAL_WITH_SEQ(reply, sequence);
return SURFACE_ERROR_OK;
}
uint32_t BufferClientProducer::GetQueueSize()
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
SEND_REQUEST(BUFFER_PRODUCER_GET_QUEUE_SIZE, arguments, reply, option);
return reply.ReadUint32();
}
SurfaceError BufferClientProducer::SetQueueSize(uint32_t queueSize)
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
arguments.WriteInt32(queueSize);
SEND_REQUEST(BUFFER_PRODUCER_SET_QUEUE_SIZE, arguments, reply, option);
int32_t ret = reply.ReadInt32();
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("Remote return %{public}d", ret);
return (SurfaceError)ret;
}
return SURFACE_ERROR_OK;
}
int32_t BufferClientProducer::GetDefaultWidth()
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
SEND_REQUEST(BUFFER_PRODUCER_GET_DEFAULT_WIDTH, arguments, reply, option);
return reply.ReadInt32();
}
int32_t BufferClientProducer::GetDefaultHeight()
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
SEND_REQUEST(BUFFER_PRODUCER_GET_DEFAULT_HEIGHT, arguments, reply, option);
return reply.ReadInt32();
}
SurfaceError BufferClientProducer::CleanCache()
{
DEFINE_MESSAGE_VARIABLES(arguments, reply, option, BLOGFE);
SEND_REQUEST(BUFFER_PRODUCER_CLEAN_CACHE, arguments, reply, option);
int32_t ret = reply.ReadInt32();
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("Remote return %{public}d", ret);
return (SurfaceError)ret;
}
return SURFACE_ERROR_OK;
}
}; // namespace OHOS

View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_manager.h"
#include <display_gralloc.h>
#include "buffer_log.h"
#define CHECK_INIT() \
do { \
if (grallocFuncs_ == nullptr) { \
SurfaceError ret = Init(); \
if (ret != SURFACE_ERROR_OK) { \
return ret; \
} \
} \
} while (0)
#define CHECK_FUNC(func) \
do { \
if (func == nullptr) { \
return SURFACE_ERROR_NOT_SUPPORT; \
} \
} while (0)
#define CHECK_BUFFER(buffer) \
do { \
if (buffer == nullptr) { \
return SURFACE_ERROR_NULLPTR; \
} \
} while (0)
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "BufferManager" };
}
BufferManager BufferManager::instance_;
SurfaceError BufferManager::Init()
{
if (grallocFuncs_ != nullptr) {
BLOGFD("BufferManager has been initialized successfully.");
return SURFACE_ERROR_OK;
}
if (GrallocInitialize(&grallocFuncs_) != DISPLAY_SUCCESS) {
BLOGFW("GrallocInitialize failed.");
return SURFACE_ERROR_INIT;
}
if (grallocFuncs_ == nullptr) {
BLOGFW("GrallocInitialize failed.");
return SURFACE_ERROR_INIT;
}
BLOGFD("funcs.AllocMem 0x%{public}s", grallocFuncs_->AllocMem ? "Yes" : "No");
BLOGFD("funcs.FreeMem 0x%{public}s", grallocFuncs_->FreeMem ? "Yes" : "No");
BLOGFD("funcs.Mmap 0x%{public}s", grallocFuncs_->Mmap ? "Yes" : "No");
BLOGFD("funcs.MmapCache 0x%{public}s", grallocFuncs_->MmapCache ? "Yes" : "No");
BLOGFD("funcs.Unmap 0x%{public}s", grallocFuncs_->Unmap ? "Yes" : "No");
BLOGFD("funcs.FlushCache 0x%{public}s", grallocFuncs_->FlushCache ? "Yes" : "No");
BLOGFD("funcs.FlushMCache 0x%{public}s", grallocFuncs_->FlushMCache ? "Yes" : "No");
BLOGFD("funcs.InvalidateCache 0x%{public}s", grallocFuncs_->InvalidateCache ? "Yes" : "No");
return SURFACE_ERROR_OK;
}
BufferManager::~BufferManager()
{
int32_t ret = GrallocUninitialize(grallocFuncs_);
if (ret != 0) {
BLOG_FAILURE("GrallocUninitialize failed with %{public}d", ret);
}
}
SurfaceError BufferManager::Alloc(BufferRequestConfig& config, sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->AllocMem);
CHECK_BUFFER(buffer);
BufferHandle* handle = nullptr;
AllocInfo info = {config.width, config.height, config.usage, (PixelFormat)config.format, DMA_MEM};
int ret = grallocFuncs_->AllocMem(&info, &handle);
if (ret == DISPLAY_SUCCESS) {
buffer->SetBufferHandle(handle);
return SURFACE_ERROR_OK;
}
BLOGFW("Failed with %{public}d", ret);
if (ret == DISPLAY_NOMEM) {
return SURFACE_ERROR_NOMEM;
}
return SURFACE_ERROR_API_FAILED;
}
SurfaceError BufferManager::Map(sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->Mmap);
CHECK_BUFFER(buffer);
BufferHandle* handle = buffer->GetBufferHandle();
void* virAddr = grallocFuncs_->Mmap(reinterpret_cast<BufferHandle*>(handle));
if (virAddr == nullptr) {
return SURFACE_ERROR_API_FAILED;
}
return SURFACE_ERROR_OK;
}
SurfaceError BufferManager::Unmap(sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->Unmap);
CHECK_BUFFER(buffer);
if (buffer->GetVirAddr() == nullptr) {
return SURFACE_ERROR_OK;
}
BufferHandle* handle = buffer->GetBufferHandle();
int32_t ret = grallocFuncs_->Unmap(reinterpret_cast<BufferHandle*>(handle));
if (ret == DISPLAY_SUCCESS) {
handle->virAddr = nullptr;
return SURFACE_ERROR_OK;
}
BLOGFW("Failed with %{public}d", ret);
return SURFACE_ERROR_API_FAILED;
}
SurfaceError BufferManager::FlushCache(sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->FlushCache);
CHECK_BUFFER(buffer);
BufferHandle* handle = buffer->GetBufferHandle();
int32_t ret = grallocFuncs_->FlushCache(reinterpret_cast<BufferHandle*>(handle));
if (ret == DISPLAY_SUCCESS) {
return SURFACE_ERROR_OK;
}
BLOGFW("Failed with %{public}d", ret);
return SURFACE_ERROR_API_FAILED;
}
SurfaceError BufferManager::InvalidateCache(sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->InvalidateCache);
CHECK_BUFFER(buffer);
BufferHandle* handle = buffer->GetBufferHandle();
int32_t ret = grallocFuncs_->InvalidateCache(reinterpret_cast<BufferHandle*>(handle));
if (ret == DISPLAY_SUCCESS) {
return SURFACE_ERROR_OK;
}
BLOGFW("Failed with %{public}d", ret);
return SURFACE_ERROR_API_FAILED;
}
SurfaceError BufferManager::Free(sptr<SurfaceBufferImpl>& buffer)
{
CHECK_INIT();
CHECK_FUNC(grallocFuncs_->FreeMem);
CHECK_BUFFER(buffer);
BufferHandle* handle = buffer->GetBufferHandle();
if (handle == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
grallocFuncs_->FreeMem(reinterpret_cast<BufferHandle*>(handle));
buffer->SetBufferHandle(nullptr);
return SURFACE_ERROR_OK;
}
} // namespace OHOS

View File

@ -0,0 +1,504 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_queue.h"
#include <algorithm>
#include <display_type.h>
#include <sys/time.h>
#include "buffer_log.h"
#include "buffer_manager.h"
#define CHECK_SEQ_CACHE_AND_STATE(sequence, cache, state_) \
do { \
if (cache.find(sequence) == cache.end()) { \
BLOG_FAILURE_ID(sequence, "not found in cache"); \
return SURFACE_ERROR_NO_ENTRY; \
} \
if (cache[sequence].state != state_) { \
BLOG_FAILURE_ID(sequence, "state is not " #state_); \
return SURFACE_ERROR_INVALID_OPERATING; \
} \
} while (0)
#define SET_SEQ_STATE(sequence, cache, state_) \
cache[sequence].state = state_
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "BufferQueue" };
constexpr int32_t SEC_TO_USEC = 1000000;
}
BufferQueue::BufferQueue()
{
BLOGFD("");
queueSize_ = SURFACE_DEFAULT_QUEUE_SIZE;
}
BufferQueue::~BufferQueue()
{
BLOGFD("");
std::lock_guard<std::mutex> lockGuard(mutex_);
for (auto it = bufferQueueCache_.begin(); it != bufferQueueCache_.end(); it++) {
FreeBuffer(it->second.buffer);
}
}
SurfaceError BufferQueue::Init()
{
return SURFACE_ERROR_OK;
}
uint32_t BufferQueue::GetUsedSize()
{
uint32_t used_size = bufferQueueCache_.size();
return used_size;
}
SurfaceError BufferQueue::PopFromFreeList(sptr<SurfaceBufferImpl>& buffer, BufferRequestConfig& config)
{
for (auto it = freeList_.begin(); it != freeList_.end(); it++) {
if (bufferQueueCache_[*it].config == config) {
buffer = bufferQueueCache_[*it].buffer;
freeList_.erase(it);
return SURFACE_ERROR_OK;
}
}
if (freeList_.empty()) {
buffer = nullptr;
return SURFACE_ERROR_NO_BUFFER;
}
buffer = bufferQueueCache_[freeList_.front()].buffer;
freeList_.pop_front();
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::PopFromDirtyList(sptr<SurfaceBufferImpl>& buffer)
{
if (!dirtyList_.empty()) {
buffer = bufferQueueCache_[dirtyList_.front()].buffer;
dirtyList_.pop_front();
return SURFACE_ERROR_OK;
} else {
buffer = nullptr;
return SURFACE_ERROR_NO_BUFFER;
}
}
SurfaceError BufferQueue::CheckRequestConfig(BufferRequestConfig& config)
{
if (0 >= config.width || config.width > SURFACE_MAX_WIDTH) {
BLOG_INVALID("config.width (0, %{public}d], now is %{public}d", SURFACE_MAX_WIDTH, config.width);
return SURFACE_ERROR_INVALID_PARAM;
}
if (0 >= config.height || config.height > SURFACE_MAX_HEIGHT) {
BLOG_INVALID("config.height (0, %{public}d], now is %{public}d", SURFACE_MAX_HEIGHT, config.height);
return SURFACE_ERROR_INVALID_PARAM;
}
uint32_t align = config.strideAlignment;
bool isValidStrideAlignment = true;
isValidStrideAlignment = isValidStrideAlignment && (SURFACE_MIN_STRIDE_ALIGNMENT <= align);
isValidStrideAlignment = isValidStrideAlignment && (SURFACE_MAX_STRIDE_ALIGNMENT >= align);
if (!isValidStrideAlignment) {
BLOG_INVALID("config.strideAlignment [%{public}d, %{public}d], now is %{public}d",
SURFACE_MIN_STRIDE_ALIGNMENT, SURFACE_MAX_STRIDE_ALIGNMENT, align);
return SURFACE_ERROR_INVALID_PARAM;
}
if (align & (align - 1)) {
BLOG_INVALID("config.strideAlignment is not power of 2 like 4, 8, 16, 32; now is %{public}d", align);
return SURFACE_ERROR_INVALID_PARAM;
}
if (0 > config.format || config.format > PIXEL_FMT_BUTT) {
BLOG_INVALID("config.format [0, %{public}d], now is %{public}d", PIXEL_FMT_BUTT, config.format);
return SURFACE_ERROR_INVALID_PARAM;
}
constexpr int32_t usageMax = HBM_USE_MEM_DMA * 2;
if (0 > config.usage || config.usage >= usageMax) {
BLOG_INVALID("config.usage [0, %{public}d), now is %{public}d", usageMax, config.usage);
return SURFACE_ERROR_INVALID_PARAM;
}
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::CheckFlushConfig(BufferFlushConfig& config)
{
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::RequestBuffer(int32_t& sequence, sptr<SurfaceBufferImpl>& buffer,
int32_t& fence, BufferRequestConfig& config,
std::vector<int32_t>& deletingBuffers)
{
if (listener_ == nullptr) {
BLOG_FAILURE_RET(SURFACE_ERROR_NO_CONSUMER);
}
// check param
SurfaceError ret = CheckRequestConfig(config);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE_API(CheckRequestConfig, ret);
return ret;
}
// dequeue from free list
std::lock_guard<std::mutex> lockGuard(mutex_);
ret = PopFromFreeList(buffer, config);
if (ret == SURFACE_ERROR_OK) {
sequence = buffer->GetSeqNum();
bool need_realloc = (config != bufferQueueCache_[sequence].config);
// config, realloc
if (need_realloc) {
DeleteBufferInCache(sequence);
ret = AllocBuffer(buffer, config);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("realloc failed");
return ret;
}
sequence = buffer->GetSeqNum();
bufferQueueCache_[sequence].config = config;
}
SET_SEQ_STATE(sequence, bufferQueueCache_, BUFFER_STATE_REQUESTED);
fence = bufferQueueCache_[sequence].fence;
deletingBuffers.insert(deletingBuffers.end(), deletingList_.begin(), deletingList_.end());
deletingList_.clear();
if (need_realloc) {
BLOG_SUCCESS_ID(sequence, "config change, realloc");
} else {
BLOG_SUCCESS_ID(sequence, "buffer cache");
buffer = nullptr;
}
return SURFACE_ERROR_OK;
}
// check queue size
if (GetUsedSize() >= GetQueueSize()) {
BLOG_FAILURE("all buffer are using");
return SURFACE_ERROR_NO_BUFFER;
}
ret = AllocBuffer(buffer, config);
if (ret == SURFACE_ERROR_OK) {
sequence = buffer->GetSeqNum();
BLOG_SUCCESS_ID(sequence, "alloc");
}
return ret;
}
SurfaceError BufferQueue::CancelBuffer(int32_t sequence)
{
std::lock_guard<std::mutex> lockGuard(mutex_);
CHECK_SEQ_CACHE_AND_STATE(sequence, bufferQueueCache_, BUFFER_STATE_REQUESTED);
SET_SEQ_STATE(sequence, bufferQueueCache_, BUFFER_STATE_RELEASED);
freeList_.push_back(sequence);
BLOG_SUCCESS_ID(sequence, "cancel");
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::FlushBuffer(int32_t sequence, int32_t fence, BufferFlushConfig& config)
{
// check param
SurfaceError ret = CheckFlushConfig(config);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE_API(CheckFlushConfig, ret);
return ret;
}
{
std::lock_guard<std::mutex> lockGuard(mutex_);
CHECK_SEQ_CACHE_AND_STATE(sequence, bufferQueueCache_, BUFFER_STATE_REQUESTED);
}
if (listener_ == nullptr) {
CancelBuffer(sequence);
return SURFACE_ERROR_NO_CONSUMER;
}
{
std::lock_guard<std::mutex> lockGuard(mutex_);
SET_SEQ_STATE(sequence, bufferQueueCache_, BUFFER_STATE_FLUSHED);
if (bufferQueueCache_[sequence].isDeleting) {
DeleteBufferInCache(sequence);
BLOG_SUCCESS_ID(sequence, "delete");
return SURFACE_ERROR_OK;
}
dirtyList_.push_back(sequence);
// api flush
ret = BufferManager::GetInstance()->FlushCache(bufferQueueCache_[sequence].buffer);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE_ID_API(sequence, FlushCache, ret);
return ret;
}
bufferQueueCache_[sequence].damage = config.damage;
if (config.timestamp == 0) {
struct timeval tv = {};
gettimeofday(&tv, nullptr);
bufferQueueCache_[sequence].timestamp = (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * SEC_TO_USEC;
} else {
bufferQueueCache_[sequence].timestamp = config.timestamp;
}
}
if (ret == SURFACE_ERROR_OK) {
if (listener_ != nullptr) {
listener_->OnBufferAvailable();
}
}
BLOG_SUCCESS_ID(sequence, "flush");
return ret;
}
SurfaceError BufferQueue::AcquireBuffer(sptr<SurfaceBufferImpl>& buffer,
int32_t& fence, int64_t& timestamp, Rect& damage)
{
// dequeue from dirty list
std::lock_guard<std::mutex> lockGuard(mutex_);
SurfaceError ret = PopFromDirtyList(buffer);
if (ret == SURFACE_ERROR_OK) {
int32_t sequence = buffer->GetSeqNum();
if (bufferQueueCache_[sequence].state != BUFFER_STATE_FLUSHED) {
BLOGFW("Warning [%{public}d], Reason: state is not BUFFER_STATE_FLUSHED", sequence);
}
SET_SEQ_STATE(sequence, bufferQueueCache_, BUFFER_STATE_ACQUIRED);
fence = bufferQueueCache_[sequence].fence;
timestamp = bufferQueueCache_[sequence].timestamp;
damage = bufferQueueCache_[sequence].damage;
BLOGFI("Success [%{public}d]", sequence);
BLOG_SUCCESS_ID(sequence, "acquire");
} else if (ret == SURFACE_ERROR_NO_BUFFER) {
BLOG_FAILURE("there is no dirty buffer");
}
return ret;
}
SurfaceError BufferQueue::ReleaseBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t fence)
{
std::lock_guard<std::mutex> lockGuard(mutex_);
if (buffer == nullptr) {
BLOG_FAILURE("buffer is nullptr");
return SURFACE_ERROR_NULLPTR;
}
int32_t sequence = buffer->GetSeqNum();
CHECK_SEQ_CACHE_AND_STATE(sequence, bufferQueueCache_, BUFFER_STATE_ACQUIRED);
SET_SEQ_STATE(sequence, bufferQueueCache_, BUFFER_STATE_RELEASED);
bufferQueueCache_[sequence].fence = fence;
if (bufferQueueCache_[sequence].isDeleting) {
DeleteBufferInCache(sequence);
BLOG_SUCCESS_ID(sequence, "delete");
} else {
freeList_.push_back(sequence);
BLOG_SUCCESS_ID(sequence, "push to free list");
}
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::AllocBuffer(sptr<SurfaceBufferImpl>& buffer, BufferRequestConfig& config)
{
buffer = new SurfaceBufferImpl();
int32_t sequence = buffer->GetSeqNum();
SurfaceError ret = BufferManager::GetInstance()->Alloc(config, buffer);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE_ID_API(sequence, Alloc, ret);
return ret;
}
if (buffer == nullptr) {
BLOG_FAILURE_ID_RET(sequence, SURFACE_ERROR_NULLPTR);
}
BufferElement ele = {
.buffer = buffer,
.state = BUFFER_STATE_REQUESTED,
.isDeleting = false,
.config = config,
.fence = -1
};
bufferQueueCache_[sequence] = ele;
ret = BufferManager::GetInstance()->Map(buffer);
if (ret == SURFACE_ERROR_OK) {
BLOG_SUCCESS_ID(sequence, "Map");
return SURFACE_ERROR_OK;
}
SurfaceError freeRet = BufferManager::GetInstance()->Free(buffer);
if (freeRet != SURFACE_ERROR_OK) {
BLOG_FAILURE_ID(sequence, "Map failed, Free failed");
} else {
BLOG_FAILURE_ID(sequence, "Map failed, Free success");
}
return ret;
}
SurfaceError BufferQueue::FreeBuffer(sptr<SurfaceBufferImpl>& buffer)
{
BLOGFD("Free [%{public}d]", buffer->GetSeqNum());
BufferManager::GetInstance()->Unmap(buffer);
BufferManager::GetInstance()->Free(buffer);
return SURFACE_ERROR_OK;
}
void BufferQueue::DeleteBufferInCache(int32_t sequence)
{
auto it = bufferQueueCache_.find(sequence);
if (it != bufferQueueCache_.end()) {
FreeBuffer(it->second.buffer);
bufferQueueCache_.erase(it);
deletingList_.push_back(sequence);
}
}
uint32_t BufferQueue::GetQueueSize()
{
return queueSize_;
}
void BufferQueue::DeleteBuffers(int32_t count)
{
if (count <= 0) {
return;
}
std::lock_guard<std::mutex> lockGuard(mutex_);
while (!freeList_.empty()) {
DeleteBufferInCache(freeList_.front());
freeList_.pop_front();
count--;
if (count <= 0) {
return;
}
}
while (!dirtyList_.empty()) {
DeleteBufferInCache(dirtyList_.front());
dirtyList_.pop_front();
count--;
if (count <= 0) {
return;
}
}
for (auto&& ele : bufferQueueCache_) {
ele.second.isDeleting = true;
if (ele.second.state == BUFFER_STATE_ACQUIRED) {
FreeBuffer(ele.second.buffer);
}
count--;
if (count <= 0) {
break;
}
}
}
SurfaceError BufferQueue::SetQueueSize(uint32_t queueSize)
{
if (queueSize <= 0) {
BLOG_INVALID("queue size (%{public}d) <= 0", queueSize);
return SURFACE_ERROR_INVALID_PARAM;
}
if (queueSize > SURFACE_MAX_QUEUE_SIZE) {
BLOG_INVALID("queue size (%{public}d) > %{public}d", queueSize, SURFACE_MAX_QUEUE_SIZE);
return SURFACE_ERROR_INVALID_PARAM;
}
DeleteBuffers(queueSize_ - queueSize);
queueSize_ = queueSize;
BLOG_SUCCESS("queue size: %{public}d", queueSize);
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::RegisterConsumerListener(sptr<IBufferConsumerListener>& listener)
{
listener_ = listener;
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::UnregisterConsumerListener()
{
listener_ = nullptr;
return SURFACE_ERROR_OK;
}
SurfaceError BufferQueue::SetDefaultWidthAndHeight(int32_t width, int32_t height)
{
if (0 >= width || width > SURFACE_MAX_WIDTH) {
BLOG_INVALID("defaultWidth (0, %{public}d], now is %{public}d", SURFACE_MAX_WIDTH, width);
return SURFACE_ERROR_INVALID_PARAM;
}
if (0 >= height || height > SURFACE_MAX_HEIGHT) {
BLOG_INVALID("defaultHeight (0, %{public}d], now is %{public}d", SURFACE_MAX_HEIGHT, height);
return SURFACE_ERROR_INVALID_PARAM;
}
defaultWidth = width;
defaultHeight = height;
return SURFACE_ERROR_OK;
}
int32_t BufferQueue::GetDefaultWidth()
{
return defaultWidth;
}
int32_t BufferQueue::GetDefaultHeight()
{
return defaultHeight;
}
SurfaceError BufferQueue::CleanCache()
{
DeleteBuffers(queueSize_);
return SURFACE_ERROR_OK;
}
}; // namespace OHOS

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_queue_consumer.h"
#include "buffer_log.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "BufferQueueConsumer" };
}
BufferQueueConsumer::BufferQueueConsumer(sptr<BufferQueue>& bufferQueue)
{
BLOGFD("");
bufferQueue_ = bufferQueue;
}
BufferQueueConsumer::~BufferQueueConsumer()
{
BLOGFD("");
}
SurfaceError BufferQueueConsumer::AcquireBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->AcquireBuffer(buffer, fence, timestamp, damage);
}
SurfaceError BufferQueueConsumer::ReleaseBuffer(sptr<SurfaceBufferImpl>& buffer, int32_t fence)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->ReleaseBuffer(buffer, fence);
}
SurfaceError BufferQueueConsumer::RegisterConsumerListener(sptr<IBufferConsumerListener>& listener)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->RegisterConsumerListener(listener);
}
SurfaceError BufferQueueConsumer::UnregisterConsumerListener()
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->UnregisterConsumerListener();
}
SurfaceError BufferQueueConsumer::SetDefaultWidthAndHeight(int32_t width, int32_t height)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->SetDefaultWidthAndHeight(width, height);
}
} // namespace OHOS

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_queue_producer.h"
#include "buffer_log.h"
#include "buffer_manager.h"
#include "buffer_utils.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "BufferQueueProducer" };
}
BufferQueueProducer::BufferQueueProducer(sptr<BufferQueue>& bufferQueue)
{
BLOGFD("");
bufferQueue_ = bufferQueue;
memberFuncMap_[BUFFER_PRODUCER_REQUEST_BUFFER] = &BufferQueueProducer::RequestBufferInner;
memberFuncMap_[BUFFER_PRODUCER_CANCEL_BUFFER] = &BufferQueueProducer::CancelBufferInner;
memberFuncMap_[BUFFER_PRODUCER_FLUSH_BUFFER] = &BufferQueueProducer::FlushBufferInner;
memberFuncMap_[BUFFER_PRODUCER_GET_QUEUE_SIZE] = &BufferQueueProducer::GetQueueSizeInner;
memberFuncMap_[BUFFER_PRODUCER_SET_QUEUE_SIZE] = &BufferQueueProducer::SetQueueSizeInner;
memberFuncMap_[BUFFER_PRODUCER_GET_DEFAULT_WIDTH] = &BufferQueueProducer::GetDefaultWidthInner;
memberFuncMap_[BUFFER_PRODUCER_GET_DEFAULT_HEIGHT] = &BufferQueueProducer::GetDefaultHeightInner;
memberFuncMap_[BUFFER_PRODUCER_CLEAN_CACHE] = &BufferQueueProducer::CleanCacheInner;
}
BufferQueueProducer::~BufferQueueProducer()
{
BLOGFD("");
}
int BufferQueueProducer::OnRemoteRequest(uint32_t code, MessageParcel& arguments,
MessageParcel& reply, MessageOption& option)
{
auto it = memberFuncMap_.find(code);
if (it == memberFuncMap_.end()) {
BLOG_FAILURE("cannot process %{public}u", code);
return 0;
}
if (it->second == nullptr) {
BLOG_FAILURE("memberFuncMap_[%{public}u] is nullptr", code);
return 0;
}
auto remoteDescriptor = arguments.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return ERR_INVALID_STATE;
}
return (this->*(it->second))(arguments, reply, option);
}
int BufferQueueProducer::RequestBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
int32_t sequence;
sptr<SurfaceBuffer> buffer;
int32_t fence = -1;
BufferRequestConfig config;
std::vector<int32_t> deletingBuffers;
ReadRequestConfig(arguments, config);
SurfaceError retval = RequestBuffer(sequence, buffer, fence, config, deletingBuffers);
reply.WriteInt32(retval);
if (retval == SURFACE_ERROR_OK) {
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
WriteFence(reply, fence);
reply.WriteInt32Vector(deletingBuffers);
WriteSurfaceBufferImpl(reply, sequence, bufferImpl);
}
return 0;
}
int BufferQueueProducer::CancelBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
int32_t sequence = arguments.ReadInt32();
SurfaceError retval = CancelBuffer(sequence);
reply.WriteInt32(retval);
return 0;
}
int BufferQueueProducer::FlushBufferInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
int32_t fence;
int32_t sequence;
BufferFlushConfig config;
sequence = arguments.ReadInt32();
ReadFence(arguments, fence);
ReadFlushConfig(arguments, config);
SurfaceError retval = FlushBuffer(sequence, fence, config);
reply.WriteInt32(retval);
return 0;
}
int BufferQueueProducer::GetQueueSizeInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
reply.WriteInt32(GetQueueSize());
return 0;
}
int BufferQueueProducer::SetQueueSizeInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
int32_t queueSize = arguments.ReadInt32();
SurfaceError retval = SetQueueSize(queueSize);
reply.WriteInt32(retval);
return 0;
}
int BufferQueueProducer::GetDefaultWidthInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
reply.WriteInt32(GetDefaultWidth());
return 0;
}
int BufferQueueProducer::GetDefaultHeightInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
reply.WriteInt32(GetDefaultHeight());
return 0;
}
int BufferQueueProducer::CleanCacheInner(MessageParcel& arguments, MessageParcel& reply, MessageOption& option)
{
reply.WriteInt32(CleanCache());
return 0;
}
SurfaceError BufferQueueProducer::RequestBuffer(int32_t& sequence, sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config, std::vector<int32_t>& deletingBuffers)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
SurfaceError ret = bufferQueue_->RequestBuffer(sequence, bufferImpl, fence, config, deletingBuffers);
buffer = bufferImpl;
return ret;
}
SurfaceError BufferQueueProducer::CancelBuffer(int32_t sequence)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->CancelBuffer(sequence);
}
SurfaceError BufferQueueProducer::FlushBuffer(int32_t sequence,
int32_t fence, BufferFlushConfig& config)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->FlushBuffer(sequence, fence, config);
}
uint32_t BufferQueueProducer::GetQueueSize()
{
if (bufferQueue_ == nullptr) {
return 0;
}
return bufferQueue_->GetQueueSize();
}
SurfaceError BufferQueueProducer::SetQueueSize(uint32_t queueSize)
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->SetQueueSize(queueSize);
}
int32_t BufferQueueProducer::GetDefaultWidth()
{
if (bufferQueue_ == nullptr) {
return 0;
}
return bufferQueue_->GetDefaultWidth();
}
int32_t BufferQueueProducer::GetDefaultHeight()
{
if (bufferQueue_ == nullptr) {
return 0;
}
return bufferQueue_->GetDefaultHeight();
}
SurfaceError BufferQueueProducer::CleanCache()
{
if (bufferQueue_ == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return bufferQueue_->CleanCache();
}
}; // namespace OHOS

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "buffer_utils.h"
#include <fcntl.h>
#include <unistd.h>
namespace OHOS {
void ReadFence(MessageParcel& parcel, int32_t& fence)
{
int32_t retFence = parcel.ReadInt32();
if (retFence < 0) {
return;
}
fence = parcel.ReadFileDescriptor();
}
void WriteFence(MessageParcel& parcel, int32_t fence)
{
if (fence >= 0 && fcntl(fence, F_GETFL) == -1 && errno == EBADF) {
fence = -1;
}
parcel.WriteInt32(fence);
if (fence < 0) {
return;
}
parcel.WriteFileDescriptor(fence);
}
void ReadRequestConfig(MessageParcel& parcel, BufferRequestConfig& config)
{
config.width = parcel.ReadInt32();
config.height = parcel.ReadInt32();
config.strideAlignment = parcel.ReadInt32();
config.format = parcel.ReadInt32();
config.usage = parcel.ReadInt32();
config.timeout = parcel.ReadInt32();
}
void WriteRequestConfig(MessageParcel& parcel, BufferRequestConfig const & config)
{
parcel.WriteInt32(config.width);
parcel.WriteInt32(config.height);
parcel.WriteInt32(config.strideAlignment);
parcel.WriteInt32(config.format);
parcel.WriteInt32(config.usage);
parcel.WriteInt32(config.timeout);
}
void ReadFlushConfig(MessageParcel& parcel, BufferFlushConfig& config)
{
config.damage.x = parcel.ReadInt32();
config.damage.y = parcel.ReadInt32();
config.damage.w = parcel.ReadInt32();
config.damage.h = parcel.ReadInt32();
config.timestamp = parcel.ReadInt64();
}
void WriteFlushConfig(MessageParcel& parcel, BufferFlushConfig const & config)
{
parcel.WriteInt32(config.damage.x);
parcel.WriteInt32(config.damage.y);
parcel.WriteInt32(config.damage.w);
parcel.WriteInt32(config.damage.h);
parcel.WriteInt64(config.timestamp);
}
void ReadSurfaceBufferImpl(MessageParcel& parcel,
int32_t& sequence, sptr<SurfaceBufferImpl>& bufferImpl)
{
sequence = parcel.ReadInt32();
if (parcel.ReadBool()) {
bufferImpl = new SurfaceBufferImpl(sequence);
auto handle = ReadBufferHandle(parcel);
bufferImpl->SetBufferHandle(handle);
}
}
void WriteSurfaceBufferImpl(MessageParcel& parcel,
int32_t sequence, sptr<SurfaceBufferImpl> const & bufferImpl)
{
parcel.WriteInt32(sequence);
parcel.WriteBool(bufferImpl != nullptr);
if (bufferImpl == nullptr) {
return;
}
bufferImpl->WriteToMessageParcel(parcel);
}
} // namespace OHOS

View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "consumer_surface.h"
#include <vector>
#include "buffer_log.h"
#include "buffer_queue_producer.h"
namespace OHOS {
namespace {
static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "ConsumerSurface" };
}
ConsumerSurface::ConsumerSurface()
{
BLOGFD("");
consumer_ = nullptr;
producer_ = nullptr;
}
ConsumerSurface::~ConsumerSurface()
{
BLOGFD("");
consumer_ = nullptr;
producer_ = nullptr;
}
SurfaceError ConsumerSurface::Init()
{
sptr<BufferQueue> queue_ = new BufferQueue();
SurfaceError ret = queue_->Init();
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("queue init failed");
return ret;
}
producer_ = new BufferQueueProducer(queue_);
consumer_ = new BufferQueueConsumer(queue_);
return SURFACE_ERROR_OK;
}
sptr<IBufferProducer> ConsumerSurface::GetProducer()
{
return producer_;
}
SurfaceError ConsumerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
SurfaceError ConsumerSurface::CancelBuffer(sptr<SurfaceBuffer>& buffer)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
SurfaceError ConsumerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
int32_t fence, BufferFlushConfig& config)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
SurfaceError ConsumerSurface::AcquireBuffer(sptr<SurfaceBuffer>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage)
{
SurfaceError ret;
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
ret = consumer_->AcquireBuffer(bufferImpl, fence, timestamp, damage);
buffer = bufferImpl;
return ret;
}
SurfaceError ConsumerSurface::ReleaseBuffer(sptr<SurfaceBuffer>& buffer, int32_t fence)
{
SurfaceError ret;
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
ret = consumer_->ReleaseBuffer(bufferImpl, fence);
buffer = bufferImpl;
return ret;
}
uint32_t ConsumerSurface::GetQueueSize()
{
return producer_->GetQueueSize();
}
SurfaceError ConsumerSurface::SetQueueSize(uint32_t queueSize)
{
return producer_->SetQueueSize(queueSize);
}
SurfaceError ConsumerSurface::SetDefaultWidthAndHeight(int32_t width, int32_t height)
{
return consumer_->SetDefaultWidthAndHeight(width, height);
}
int32_t ConsumerSurface::GetDefaultWidth()
{
return producer_->GetDefaultWidth();
}
int32_t ConsumerSurface::GetDefaultHeight()
{
return producer_->GetDefaultHeight();
}
SurfaceError ConsumerSurface::SetUserData(const std::string& key, const std::string& val)
{
if (userData_.size() >= SURFACE_MAX_USER_DATA_COUNT) {
return SURFACE_ERROR_OUT_OF_RANGE;
}
userData_[key] = val;
return SURFACE_ERROR_OK;
}
std::string ConsumerSurface::GetUserData(const std::string& key)
{
if (userData_.find(key) != userData_.end()) {
return userData_[key];
}
return "";
}
SurfaceError ConsumerSurface::RegisterConsumerListener(sptr<IBufferConsumerListener>& listener)
{
return consumer_->RegisterConsumerListener(listener);
}
SurfaceError ConsumerSurface::UnregisterConsumerListener()
{
return consumer_->UnregisterConsumerListener();
}
SurfaceError ConsumerSurface::CleanCache()
{
return producer_->CleanCache();
}
} // namespace OHOS

View File

@ -0,0 +1,192 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "producer_surface.h"
#include "buffer_log.h"
#include "buffer_manager.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "ProducerSurface" };
}
ProducerSurface::ProducerSurface(sptr<IBufferProducer>& producer)
{
BLOGFD("");
producer_ = producer;
}
ProducerSurface::~ProducerSurface()
{
BLOGFD("");
if (IsRemote()) {
for (auto it = bufferProducerCache_.begin(); it != bufferProducerCache_.end(); it++) {
if (it->second->GetVirAddr() != nullptr) {
BufferManager::GetInstance()->Unmap(it->second);
}
}
}
producer_ = nullptr;
}
SurfaceError ProducerSurface::Init()
{
return SURFACE_ERROR_OK;
}
sptr<IBufferProducer> ProducerSurface::GetProducer()
{
return producer_;
}
SurfaceError ProducerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
int32_t& fence, BufferRequestConfig& config)
{
std::vector<int32_t> deletingBuffers;
int32_t sequence;
SurfaceError ret = GetProducer()->RequestBuffer(sequence, buffer, fence, config, deletingBuffers);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("Producer report %{public}s", SurfaceErrorStr(ret).c_str());
return ret;
}
// add cache
if (buffer != nullptr && IsRemote()) {
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
ret = BufferManager::GetInstance()->Map(bufferImpl);
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE_ID(sequence, "Map failed");
} else {
BLOG_SUCCESS_ID(sequence, "Map");
}
}
if (buffer != nullptr) {
bufferProducerCache_[sequence] = SurfaceBufferImpl::FromBase(buffer);
} else {
buffer = bufferProducerCache_[sequence];
}
sptr<SurfaceBufferImpl> bufferImpl = SurfaceBufferImpl::FromBase(buffer);
ret = BufferManager::GetInstance()->InvalidateCache(bufferImpl);
if (ret != SURFACE_ERROR_OK) {
BLOGFW("Warning [%{public}d], InvalidateCache failed", sequence);
}
for (auto it = deletingBuffers.begin(); it != deletingBuffers.end(); it++) {
if (IsRemote() && bufferProducerCache_[*it]->GetVirAddr() != nullptr) {
BufferManager::GetInstance()->Unmap(bufferProducerCache_[*it]);
}
bufferProducerCache_.erase(*it);
}
return ret;
}
SurfaceError ProducerSurface::CancelBuffer(sptr<SurfaceBuffer>& buffer)
{
if (buffer == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return GetProducer()->CancelBuffer(SurfaceBufferImpl::FromBase(buffer)->GetSeqNum());
}
SurfaceError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
int32_t fence, BufferFlushConfig& config)
{
if (buffer == nullptr) {
return SURFACE_ERROR_NULLPTR;
}
return GetProducer()->FlushBuffer(SurfaceBufferImpl::FromBase(buffer)->GetSeqNum(), fence, config);
}
SurfaceError ProducerSurface::AcquireBuffer(sptr<SurfaceBuffer>& buffer, int32_t& fence,
int64_t& timestamp, Rect& damage)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
SurfaceError ProducerSurface::ReleaseBuffer(sptr<SurfaceBuffer>& buffer, int32_t fence)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
uint32_t ProducerSurface::GetQueueSize()
{
return producer_->GetQueueSize();
}
SurfaceError ProducerSurface::SetQueueSize(uint32_t queueSize)
{
return producer_->SetQueueSize(queueSize);
}
SurfaceError ProducerSurface::SetDefaultWidthAndHeight(int32_t width, int32_t height)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
int32_t ProducerSurface::GetDefaultWidth()
{
return producer_->GetDefaultWidth();
}
int32_t ProducerSurface::GetDefaultHeight()
{
return producer_->GetDefaultHeight();
}
SurfaceError ProducerSurface::SetUserData(const std::string& key, const std::string& val)
{
if (userData_.size() >= SURFACE_MAX_USER_DATA_COUNT) {
return SURFACE_ERROR_OUT_OF_RANGE;
}
userData_[key] = val;
return SURFACE_ERROR_OK;
}
std::string ProducerSurface::GetUserData(const std::string& key)
{
if (userData_.find(key) != userData_.end()) {
return userData_[key];
}
return "";
}
SurfaceError ProducerSurface::RegisterConsumerListener(sptr<IBufferConsumerListener>& listener)
{
return SURFACE_ERROR_NOT_SUPPORT;
}
SurfaceError ProducerSurface::UnregisterConsumerListener()
{
return SURFACE_ERROR_NOT_SUPPORT;
}
bool ProducerSurface::IsRemote()
{
return producer_->AsObject()->IsProxyObject();
}
SurfaceError ProducerSurface::CleanCache()
{
return producer_->CleanCache();
}
} // namespace OHOS

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <surface.h>
#include <hilog/log.h>
#include "buffer_log.h"
#include "consumer_surface.h"
#include "producer_surface.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "Surface" };
}
sptr<Surface> Surface::CreateSurfaceAsConsumer()
{
sptr<ConsumerSurface> surface = new ConsumerSurface();
SurfaceError ret = surface->Init();
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("consumer surface init failed");
return nullptr;
}
return surface;
}
sptr<Surface> Surface::CreateSurfaceAsProducer(sptr<IBufferProducer>& producer)
{
sptr<ProducerSurface> surface = new ProducerSurface(producer);
SurfaceError ret = surface->Init();
if (ret != SURFACE_ERROR_OK) {
BLOG_FAILURE("producer surface init failed");
return nullptr;
}
return surface;
}
} // namespace OHOS

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "surface_buffer_impl.h"
#include <mutex>
#include <message_parcel.h>
#include <securec.h>
#include "buffer_log.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "SurfaceBufferImpl" };
}
SurfaceBufferImpl::SurfaceBufferImpl()
{
BLOGFD("");
{
static std::mutex mutex;
mutex.lock();
static int sequence_number_ = 0;
this->bufferData_.sequenceNumber = sequence_number_++;
mutex.unlock();
}
this->bufferData_.handle_ = nullptr;
}
SurfaceBufferImpl::SurfaceBufferImpl(int seqNum)
{
BLOGFD("");
bufferData_.sequenceNumber = seqNum;
bufferData_.handle_ = nullptr;
}
SurfaceBufferImpl::~SurfaceBufferImpl()
{
BLOGFD("");
for (auto it = this->extraDatas_.begin(); it != this->extraDatas_.end(); it++) {
if (it->second.value) {
delete[] reinterpret_cast<uint8_t*>(it->second.value);
}
}
if (this->bufferData_.handle_) {
delete[] reinterpret_cast<uint8_t*>(this->bufferData_.handle_);
}
}
SurfaceBufferImpl* SurfaceBufferImpl::FromBase(sptr<SurfaceBuffer>& buffer)
{
return static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
}
BufferHandle* SurfaceBufferImpl::GetBufferHandle() const
{
return bufferData_.handle_;
}
int32_t SurfaceBufferImpl::GetWidth() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->width;
}
int32_t SurfaceBufferImpl::GetHeight() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->height;
}
int32_t SurfaceBufferImpl::GetFormat() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->format;
}
int64_t SurfaceBufferImpl::GetUsage() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->usage;
}
uint64_t SurfaceBufferImpl::GetPhyAddr() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return 0;
}
return this->bufferData_.handle_->phyAddr;
}
int32_t SurfaceBufferImpl::GetKey() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->key;
}
void* SurfaceBufferImpl::GetVirAddr() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return nullptr;
}
return this->bufferData_.handle_->virAddr;
}
int32_t SurfaceBufferImpl::GetFileDescriptor() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return -1;
}
return this->bufferData_.handle_->fd;
}
uint32_t SurfaceBufferImpl::GetSize() const
{
if (this->bufferData_.handle_ == nullptr) {
BLOGFW("handle is nullptr");
return 0;
}
return this->bufferData_.handle_->size;
}
SurfaceError SurfaceBufferImpl::SetInt32(uint32_t key, int32_t val)
{
ExtraData int32 = {
.value = &val,
.size = sizeof(int32_t),
.type = EXTRA_DATA_TYPE_INT32,
};
return SetData(key, int32);
}
SurfaceError SurfaceBufferImpl::GetInt32(uint32_t key, int32_t& val)
{
ExtraData int32;
SurfaceError ret = GetData(key, int32);
if (ret == SURFACE_ERROR_OK) {
if (int32.type == EXTRA_DATA_TYPE_INT32) {
val = *reinterpret_cast<int32_t*>(int32.value);
} else {
return SURFACE_ERROR_TYPE_ERROR;
}
}
return ret;
}
SurfaceError SurfaceBufferImpl::SetInt64(uint32_t key, int64_t val)
{
ExtraData int64 = {
.value = &val,
.size = sizeof(int64_t),
.type = EXTRA_DATA_TYPE_INT64,
};
return SetData(key, int64);
}
SurfaceError SurfaceBufferImpl::GetInt64(uint32_t key, int64_t& val)
{
ExtraData int64;
SurfaceError ret = GetData(key, int64);
if (ret == SURFACE_ERROR_OK) {
if (int64.type == EXTRA_DATA_TYPE_INT64) {
val = *reinterpret_cast<int64_t*>(int64.value);
} else {
return SURFACE_ERROR_TYPE_ERROR;
}
}
return ret;
}
SurfaceError SurfaceBufferImpl::SetData(uint32_t key, ExtraData data)
{
if (data.type <= EXTRA_DATA_TYPE_MIN || data.type >= EXTRA_DATA_TYPE_MAX) {
BLOG_INVALID("data.type is out of range");
return SURFACE_ERROR_INVALID_PARAM;
}
if (data.size <= 0 || data.size > sizeof(int64_t)) {
BLOG_INVALID("data.size is out of range");
return SURFACE_ERROR_INVALID_PARAM;
}
if (this->extraDatas_.size() > SURFACE_MAX_USER_DATA_COUNT) {
BLOGFW("SurfaceBuffer has too many extra data, cannot save one more!!!");
return SURFACE_ERROR_OUT_OF_RANGE;
}
ExtraData mapData;
SurfaceError ret = GetData(key, mapData);
if (ret == SURFACE_ERROR_OK) {
delete[] reinterpret_cast<uint8_t*>(mapData.value);
}
mapData = data;
mapData.value = new uint8_t[mapData.size];
errno_t reterr = memcpy_s(mapData.value, mapData.size, data.value, data.size);
if (reterr) {
BLOGFD("memcpy_s failed with %{public}d", reterr);
}
this->extraDatas_[key] = mapData;
return SURFACE_ERROR_OK;
}
SurfaceError SurfaceBufferImpl::GetData(uint32_t key, ExtraData& data)
{
auto it = this->extraDatas_.find(key);
if (it == this->extraDatas_.end()) {
return SURFACE_ERROR_NO_ENTRY;
}
data = it->second;
return SURFACE_ERROR_OK;
}
void SurfaceBufferImpl::SetBufferHandle(BufferHandle* handle)
{
bufferData_.handle_ = handle;
}
BufferHandle* SurfaceBufferImpl::GetBufferHandle()
{
return bufferData_.handle_;
}
void SurfaceBufferImpl::WriteToMessageParcel(MessageParcel& parcel)
{
if (bufferData_.handle_ == nullptr) {
BLOG_FAILURE("bufferData_.handle_ is nullptr");
return;
}
bool ret = WriteBufferHandle(parcel, *bufferData_.handle_);
if (ret == false) {
BLOG_FAILURE("WriteBufferHandle return false");
}
}
int32_t SurfaceBufferImpl::GetSeqNum()
{
return this->bufferData_.sequenceNumber;
}
} // namespace OHOS

View File

@ -0,0 +1,18 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("test") {
testonly = true
deps = [ "unittest:unittest" ]
}

View File

@ -0,0 +1,47 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Build surface_test_common.a {{{
config("surface_test_common_public_config") {
include_dirs = [
".",
"//foundation/graphic/standard/frameworks/surface/include",
]
cflags = [
"-Dprivate=public",
"-Dprotected=public",
]
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
}
ohos_static_library("surface_test_common") {
public_configs = [ ":surface_test_common_public_config" ]
public_deps = [ "//foundation/graphic/standard:libsurface" ]
}
## Build surface_test_common.a }}}
group("unittest") {
testonly = true
deps = [
"local:test",
"remote:test",
]
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_ENVIRONMENTS_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_ENVIRONMENTS_H
#define IPC_QUEUE_SAID 654321
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_ENVIRONMENTS_H

View File

@ -0,0 +1,28 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
group("test") {
testonly = true
deps = [
"buffer_manager:test",
"buffer_queue:test",
"buffer_queue_consumer:test",
"buffer_queue_producer:test",
"consumer_surface:test",
"producer_surface:test",
"surface_buffer_impl:test",
]
}

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_buffer_manager_test {{{
ohos_unittest("surface_local_buffer_manager_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_buffer_manager_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_buffer_manager_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_buffer_manager_test" ]
}

View File

@ -0,0 +1,235 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_buffer_manager_test.h"
#include <securec.h>
#include <display_type.h>
#include <gtest/gtest.h>
#include <surface_type.h>
#include "buffer_manager.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
sptr<SurfaceBufferImpl> buffer;
class LocalBufferManagerTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
buffer = new SurfaceBufferImpl();
}
static void TearDownTestCase(void)
{
buffer = nullptr;
}
};
HWTEST_F(LocalBufferManagerTest, GetInstance, testing::ext::TestSize.Level0)
{
ASSERT_NE(BufferManager::GetInstance(), nullptr);
}
HWTEST_F(LocalBufferManagerTest, Init, testing::ext::TestSize.Level0)
{
SurfaceError ret = BufferManager::GetInstance()->Init();
ASSERT_EQ(ret, SURFACE_ERROR_OK);
auto pFun1 = BufferManager::GetInstance()->grallocFuncs_;
ret = BufferManager::GetInstance()->Init();
ASSERT_EQ(ret, SURFACE_ERROR_OK);
auto pFun2 = BufferManager::GetInstance()->grallocFuncs_;
ASSERT_EQ(pFun1, pFun2);
}
HWTEST_F(LocalBufferManagerTest, Alloc, testing::ext::TestSize.Level0)
{
ASSERT_EQ(buffer->GetBufferHandle(), nullptr);
SurfaceError ret = BufferManager::GetInstance()->Alloc(g_requestConfig, buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
BufferHandle* handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
}
HWTEST_F(LocalBufferManagerTest, Map, testing::ext::TestSize.Level0)
{
BufferHandle* handle;
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
SurfaceError ret = BufferManager::GetInstance()->Map(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_NE(handle->virAddr, nullptr);
}
HWTEST_F(LocalBufferManagerTest, FlushBufferBeforeUnmap, testing::ext::TestSize.Level0)
{
BufferHandle* handle;
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_NE(handle->virAddr, nullptr);
SurfaceError ret = BufferManager::GetInstance()->FlushCache(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_NE(handle->virAddr, nullptr);
}
HWTEST_F(LocalBufferManagerTest, Unmap, testing::ext::TestSize.Level0)
{
BufferHandle* handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_NE(handle->virAddr, nullptr);
SurfaceError ret = BufferManager::GetInstance()->Unmap(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
}
HWTEST_F(LocalBufferManagerTest, FlushBufferAfterUnmap, testing::ext::TestSize.Level0)
{
BufferHandle* handle;
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
SurfaceError ret = BufferManager::GetInstance()->FlushCache(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
}
HWTEST_F(LocalBufferManagerTest, Free, testing::ext::TestSize.Level0)
{
BufferHandle* handle;
handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
SurfaceError ret = BufferManager::GetInstance()->Free(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_EQ(handle, nullptr);
}
/*
* Feature: check display gralloc cma leak
* Function: graphic
* SubFunction: gralloc
* FunctionPoints: run alloc and free to check cma is no leak
* EnvConditions: system running normally, no other application is allocing
* CaseDescription: 1. get cma free
* 2. alloc buffer 3*1024KB
* 3. free buffer
* 4. get cma free, get diff
* 5. diff should less then 200KB
*/
HWTEST_F(LocalBufferManagerTest, CMALeak, testing::ext::TestSize.Level0)
{
// 0. buffer size = 1024KB
constexpr uint32_t width = 1024 * 3;
constexpr uint32_t height = 1024 / 4;
constexpr uint32_t strideAlignment = 8;
BufferRequestConfig requestConfig = {
.width = width,
.height = height,
.strideAlignment = strideAlignment,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
// 1. get cma free
auto getCmaFree = []() -> uint32_t {
FILE *fp = fopen("/proc/meminfo", "r");
if (fp == nullptr) {
GTEST_LOG_(INFO) << "fopen return " << errno << std::endl;
return 0;
}
constexpr int keyLength = 32;
char key[keyLength];
int cmaFree = 0;
while (fscanf_s(fp, "%s%d%*s", key, sizeof(key), &cmaFree) > 0) {
if (strcmp(key, "CmaFree:") == 0) {
return cmaFree;
}
}
fclose(fp);
return 0;
};
int32_t first = getCmaFree();
// 2. alloc
sptr<SurfaceBufferImpl> buffer = new SurfaceBufferImpl();
SurfaceError ret = BufferManager::GetInstance()->Alloc(requestConfig, buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
auto handle = buffer->GetBufferHandle();
ASSERT_NE(handle, nullptr);
ASSERT_EQ(handle->virAddr, nullptr);
// 3. free
ret = BufferManager::GetInstance()->Free(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
handle = buffer->GetBufferHandle();
ASSERT_EQ(handle, nullptr);
// 4. get cma free again
int32_t third = getCmaFree();
// 5. diff should less then 200KB
GTEST_LOG_(INFO) << "diff: " << first - third;
ASSERT_LT(first - third, 200);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_MANAGER_LOCAL_BUFFER_MANAGER_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_MANAGER_LOCAL_BUFFER_MANAGER_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_MANAGER_LOCAL_BUFFER_MANAGER_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_buffer_queue_test {{{
ohos_unittest("surface_local_buffer_queue_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_buffer_queue_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_buffer_queue_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_buffer_queue_test" ]
}

View File

@ -0,0 +1,476 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_buffer_queue_test.h"
#include <map>
#include <vector>
#include <display_gralloc.h>
#include <gtest/gtest.h>
#include <surface_type.h>
#include "buffer_manager.h"
#include "buffer_queue.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
static int64_t timestamp;
static Rect damage;
static sptr<BufferQueue> bq;
static std::map<int32_t, sptr<SurfaceBufferImpl>> cache;
static std::vector<int32_t> deletingBuffers;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class LocalBufferQueueTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
bq = new BufferQueue();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
bq->RegisterConsumerListener(listener);
}
static void TearDownTestCase(void)
{
bq = nullptr;
}
};
HWTEST_F(LocalBufferQueueTest, Init, testing::ext::TestSize.Level0)
{
SurfaceError ret = bq->Init();
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, QueueSize1, testing::ext::TestSize.Level0)
{
ASSERT_EQ(bq->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
SurfaceError ret = bq->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bq->GetQueueSize(), 2u);
ASSERT_EQ(bq->queueSize_, 2u);
}
HWTEST_F(LocalBufferQueueTest, QueueSize2, testing::ext::TestSize.Level0)
{
SurfaceError ret = bq->SetQueueSize(-1);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
ASSERT_EQ(bq->GetQueueSize(), 2u);
ASSERT_EQ(bq->queueSize_, 2u);
ret = bq->SetQueueSize(0);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
ASSERT_EQ(bq->GetQueueSize(), 2u);
ASSERT_EQ(bq->queueSize_, 2u);
}
HWTEST_F(LocalBufferQueueTest, ReqFluAcqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
// first request
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ASSERT_GE(sequence, 0);
// add cache
cache[sequence] = buffer;
// buffer queue will map
uint8_t* addr1 = reinterpret_cast<uint8_t*>(buffer->GetVirAddr());
ASSERT_NE(addr1, nullptr);
addr1[0] = 5;
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
uint8_t* addr2 = reinterpret_cast<uint8_t*>(buffer->GetVirAddr());
ASSERT_NE(addr2, nullptr);
if (addr2 != nullptr) {
ASSERT_EQ(addr2[0], 5u);
}
ret = bq->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
// not first request
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_EQ(buffer, nullptr);
ret = bq->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
// not first request
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_EQ(buffer, nullptr);
ret = bq->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->CancelBuffer(sequence);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqFluFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
// not first request
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_EQ(buffer, nullptr);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, AcqRelRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t flushFence;
SurfaceError ret = bq->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqReqReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer1;
sptr<SurfaceBufferImpl> buffer2;
sptr<SurfaceBufferImpl> buffer3;
int32_t releaseFence;
int32_t sequence1 = -1;
int32_t sequence2 = -1;
int32_t sequence3 = -1;
SurfaceError ret;
// not alloc
ret = bq->RequestBuffer(sequence1, buffer1, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence1, 0);
ASSERT_EQ(buffer1, nullptr);
// alloc
ret = bq->RequestBuffer(sequence2, buffer2, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence2, 0);
ASSERT_NE(buffer2, nullptr);
cache[sequence2] = buffer2;
// no buffer
ret = bq->RequestBuffer(sequence3, buffer3, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(sequence3, -1);
ASSERT_EQ(buffer3, nullptr);
ret = bq->CancelBuffer(sequence1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->CancelBuffer(sequence2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->CancelBuffer(sequence3);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
// not alloc
SurfaceError ret = bq->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_EQ(buffer, nullptr);
buffer = cache[sequence];
ret = bq->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, AcqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t flushFence;
// acq from last test
SurfaceError ret = bq->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
int32_t sequence;
for (auto it = cache.begin(); it != cache.end(); it++) {
if (it->second == buffer) {
sequence = it->first;
}
}
ASSERT_GE(sequence, 0);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ReqDeleteing, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
BufferRequestConfig deleteconfig = g_requestConfig;
deleteconfig.width = 1921;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, deleteconfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(deletingBuffers.size(), 1u);
ASSERT_GE(sequence, 0);
ASSERT_NE(buffer, nullptr);
ret = bq->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueTest, ConfigWidth_LE_Min, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.width = -1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigWidth_GE_Max, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.width = SURFACE_MAX_WIDTH + 1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigHeight_LE_Min, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.height = -1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigHeight_GE_Max, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.height = SURFACE_MAX_HEIGHT + 1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigStrideAlignment_LE_Min, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.strideAlignment = SURFACE_MIN_STRIDE_ALIGNMENT - 1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigStrideAlignment_GE_Max, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.strideAlignment = SURFACE_MAX_STRIDE_ALIGNMENT + 1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigStrideAlignment_NOT_POW_2, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.strideAlignment = 3;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigFormat_LE_Min, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.format = -1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigFormat_GE_Max, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.format = PIXEL_FMT_BUTT + 1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigUsage_LE_Min, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.usage = -1;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
HWTEST_F(LocalBufferQueueTest, ConfigUsage_GE_Max, testing::ext::TestSize.Level0)
{
BufferRequestConfig config = g_requestConfig;
config.usage = HBM_USE_MEM_DMA * 2;
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, config, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_INVALID_PARAM);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_LOCAL_BUFFER_QUEUE_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_LOCAL_BUFFER_QUEUE_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_LOCAL_BUFFER_QUEUE_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_buffer_queue_consumer_test {{{
ohos_unittest("surface_local_buffer_queue_consumer_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_buffer_queue_consumer_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_buffer_queue_consumer_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_buffer_queue_consumer_test" ]
}

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_buffer_queue_consumer_test.h"
#include <vector>
#include <display_type.h>
#include <gtest/gtest.h>
#include <surface_type.h>
#include "buffer_queue_consumer.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
int64_t timestamp;
Rect damage;
sptr<BufferQueue> bq;
sptr<BufferQueueConsumer> bqc;
std::vector<int32_t> deletingBuffers;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class LocalBufferQueueConsumerTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
bq = new BufferQueue();
bq->Init();
bqc = new BufferQueueConsumer(bq);
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
bqc->RegisterConsumerListener(listener);
}
static void TearDownTestCase(void)
{
bq = nullptr;
bqc = nullptr;
}
};
HWTEST_F(LocalBufferQueueConsumerTest, AcqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_NE(buffer, nullptr);
uint8_t* addr1 = reinterpret_cast<uint8_t*>(buffer->GetVirAddr());
ASSERT_NE(addr1, nullptr);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqc->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqc->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueConsumerTest, AcqRelRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBufferImpl> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bq->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_GE(sequence, 0);
ASSERT_EQ(buffer, nullptr);
ret = bq->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqc->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqc->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqc->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_CONSUMER_LOCAL_BUFFER_QUEUE_CONSUMER_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_CONSUMER_LOCAL_BUFFER_QUEUE_CONSUMER_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_CONSUMER_LOCAL_BUFFER_QUEUE_CONSUMER_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_buffer_queue_producer_test {{{
ohos_unittest("surface_local_buffer_queue_producer_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_buffer_queue_producer_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_buffer_queue_producer_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_buffer_queue_producer_test" ]
}

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_buffer_queue_producer_test.h"
#include <vector>
#include <display_type.h>
#include <gtest/gtest.h>
#include <surface_type.h>
#include "buffer_queue_producer.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
static int64_t timestamp;
static Rect damage;
static sptr<BufferQueue> bq;
static sptr<BufferQueueProducer> bqp;
static std::vector<int32_t> deletingBuffers;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class LocalBufferQueueProducerTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
bq = new BufferQueue();
bq->Init();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
bq->RegisterConsumerListener(listener);
bqp = new BufferQueueProducer(bq);
}
static void TearDownTestCase(void)
{
bq = nullptr;
bqp = nullptr;
}
};
HWTEST_F(LocalBufferQueueProducerTest, QueueSize, testing::ext::TestSize.Level0)
{
ASSERT_EQ(bqp->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
SurfaceError ret = bqp->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->GetQueueSize(), 2u);
ASSERT_EQ(bq->queueSize_, 2u);
}
HWTEST_F(LocalBufferQueueProducerTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bqp->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueProducerTest, ReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bqp->RequestBuffer(sequence,
buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->CancelBuffer(sequence);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueProducerTest, ReqReqReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer1;
sptr<SurfaceBuffer> buffer2;
sptr<SurfaceBuffer> buffer3;
int32_t releaseFence;
int32_t sequence1;
int32_t sequence2;
int32_t sequence3;
SurfaceError ret;
ret = bqp->RequestBuffer(sequence1, buffer1, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer1, nullptr);
ret = bqp->RequestBuffer(sequence2, buffer2, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer2, nullptr);
ret = bqp->RequestBuffer(sequence3, buffer3, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer3, nullptr);
ret = bqp->CancelBuffer(sequence1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->CancelBuffer(sequence2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->CancelBuffer(sequence3);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueProducerTest, ReqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bqp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(bufferImpl, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalBufferQueueProducerTest, ReqFluFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bqp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bqp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(bufferImpl, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_PRODUCER_LOCAL_BUFFER_QUEUE_PRODUCER_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_PRODUCER_LOCAL_BUFFER_QUEUE_PRODUCER_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_BUFFER_QUEUE_PRODUCER_LOCAL_BUFFER_QUEUE_PRODUCER_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_consumer_surface_test {{{
ohos_unittest("surface_local_consumer_surface_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_consumer_surface_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_consumer_surface_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_consumer_surface_test" ]
}

View File

@ -0,0 +1,289 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_consumer_surface_test.h"
#include <cstdlib>
#include <display_type.h>
#include <gtest/gtest.h>
#include <securec.h>
#include <surface.h>
#include <surface_buffer.h>
#include "buffer_queue_producer.h"
#include "consumer_surface.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
static int64_t timestamp;
static Rect damage;
static sptr<Surface> cs;
static sptr<Surface> ps;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class LocalConsumerSurfaceTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
cs = Surface::CreateSurfaceAsConsumer();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
cs->RegisterConsumerListener(listener);
auto p = cs->GetProducer();
ps = Surface::CreateSurfaceAsProducer(p);
}
static void TearDownTestCase(void)
{
cs = nullptr;
}
};
HWTEST_F(LocalConsumerSurfaceTest, ConsumerSurface, testing::ext::TestSize.Level0)
{
ASSERT_NE(cs, nullptr);
sptr<ConsumerSurface> qs = static_cast<ConsumerSurface*>(cs.GetRefPtr());
ASSERT_NE(qs, nullptr);
ASSERT_NE(qs->producer_, nullptr);
ASSERT_NE(qs->consumer_, nullptr);
}
HWTEST_F(LocalConsumerSurfaceTest, QueueSize, testing::ext::TestSize.Level0)
{
ASSERT_EQ(cs->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
SurfaceError ret = cs->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = cs->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(cs->GetQueueSize(), 2u);
}
HWTEST_F(LocalConsumerSurfaceTest, ReqFluReqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
SurfaceError ret = cs->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = ps->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = cs->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = ps->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = ps->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = ps->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalConsumerSurfaceTest, AcqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
SurfaceError ret = cs->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = cs->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalConsumerSurfaceTest, AcqRelRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
SurfaceError ret = cs->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = cs->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = cs->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalConsumerSurfaceTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int releaseFence;
SurfaceError ret = cs->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = ps->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = cs->CancelBuffer(buffer);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = ps->CancelBuffer(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalConsumerSurfaceTest, SetQueueSizeDeleting, testing::ext::TestSize.Level0)
{
sptr<ConsumerSurface> qs = static_cast<ConsumerSurface*>(cs.GetRefPtr());
sptr<BufferQueueProducer> bqp = static_cast<BufferQueueProducer*>(qs->producer_.GetRefPtr());
ASSERT_EQ(bqp->bufferQueue_->queueSize_, 2u);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 2u);
SurfaceError ret = cs->SetQueueSize(1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
ret = cs->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
}
HWTEST_F(LocalConsumerSurfaceTest, UserData, testing::ext::TestSize.Level0)
{
SurfaceError ret;
std::string strs[SURFACE_MAX_USER_DATA_COUNT];
constexpr int32_t stringLengthMax = 32;
char str[stringLengthMax] = {};
for (int i = 0; i < SURFACE_MAX_USER_DATA_COUNT; i++) {
auto secRet = snprintf_s(str, sizeof(str), sizeof(str) - 1, "%d", i);
ASSERT_GT(secRet, 0);
strs[i] = str;
ret = cs->SetUserData(strs[i], "magic");
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
ret = cs->SetUserData("-1", "error");
ASSERT_NE(ret, SURFACE_ERROR_OK);
std::string retStr;
for (int i = 0; i < SURFACE_MAX_USER_DATA_COUNT; i++) {
retStr = cs->GetUserData(strs[i]);
ASSERT_EQ(retStr, "magic");
}
}
HWTEST_F(LocalConsumerSurfaceTest, RegisterConsumerListener, testing::ext::TestSize.Level0)
{
class TestConsumerListener : public IBufferConsumerListener {
public:
void OnBufferAvailable() override {
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
cs->AcquireBuffer(buffer, flushFence, timestamp, damage);
int32_t* p = (int32_t*)buffer->GetVirAddr();
if (p != nullptr) {
for (int32_t i = 0; i < 128; i++) {
ASSERT_EQ(p[i], i);
}
}
cs->ReleaseBuffer(buffer, -1);
}
};
sptr<IBufferConsumerListener> listener = new TestConsumerListener();
SurfaceError ret = cs->RegisterConsumerListener(listener);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
sptr<SurfaceBuffer> buffer;
int releaseFence;
ret = ps->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
int32_t* p = (int32_t*)buffer->GetVirAddr();
if (p != nullptr) {
for (int32_t i = 0; i < 128; i++) {
p[i] = i;
}
}
ret = ps->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalConsumerSurfaceTest, RegisterConsumerListenerWithParam, testing::ext::TestSize.Level0)
{
class TestConsumerListener : public IBufferConsumerListener {
public:
void OnBufferAvailable() override {}
};
sptr<IBufferConsumerListener> listener = new TestConsumerListener();
SurfaceError ret = cs->RegisterConsumerListener(listener);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
sptr<SurfaceBuffer> buffer;
int releaseFence;
ret = ps->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
int32_t* p = (int32_t*)buffer->GetVirAddr();
if (p != nullptr) {
for (int32_t i = 0; i < g_requestConfig.width * g_requestConfig.height; i++) {
p[i] = i;
}
}
ret = ps->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_CONSUMER_SURFACE_LOCAL_CONSUMER_SURFACE_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_CONSUMER_SURFACE_LOCAL_CONSUMER_SURFACE_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_CONSUMER_SURFACE_LOCAL_CONSUMER_SURFACE_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_producer_surface_test {{{
ohos_unittest("surface_local_producer_surface_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_producer_surface_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_producer_surface_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_producer_surface_test" ]
}

View File

@ -0,0 +1,279 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_producer_surface_test.h"
#include <cstdlib>
#include <display_type.h>
#include <gtest/gtest.h>
#include <securec.h>
#include <surface.h>
#include <surface_buffer.h>
#include "buffer_queue_producer.h"
#include "consumer_surface.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
int64_t timestamp;
Rect damage;
sptr<Surface> surface_;
sptr<IBufferProducer> producer;
sptr<Surface> surface;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class LocalProducerSurfaceTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
surface_ = Surface::CreateSurfaceAsConsumer();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
surface_->RegisterConsumerListener(listener);
producer = surface_->GetProducer();
surface = Surface::CreateSurfaceAsProducer(producer);
}
static void TearDownTestCase(void)
{
surface_ = nullptr;
producer = nullptr;
surface = nullptr;
}
};
HWTEST_F(LocalProducerSurfaceTest, ProducerSurface, testing::ext::TestSize.Level0)
{
ASSERT_NE(surface, nullptr);
}
HWTEST_F(LocalProducerSurfaceTest, QueueSize, testing::ext::TestSize.Level0)
{
ASSERT_EQ(surface->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
SurfaceError ret = surface->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(surface->GetQueueSize(), 2u);
}
HWTEST_F(LocalProducerSurfaceTest, ReqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = surface->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, ReqFluFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = surface->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->FlushBuffer(buffer, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, AcqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t flushFence;
SurfaceError ret = surface->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = surface->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = surface_->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface_->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface_->AcquireBuffer(buffer, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface_->ReleaseBuffer(buffer, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, ReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, ReqReqReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
sptr<SurfaceBuffer> buffer1;
sptr<SurfaceBuffer> buffer2;
int releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->RequestBuffer(buffer1, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->RequestBuffer(buffer2, releaseFence, g_requestConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer2);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, SetQueueSizeDeleting, testing::ext::TestSize.Level0)
{
sptr<ConsumerSurface> cs = static_cast<ConsumerSurface*>(surface_.GetRefPtr());
sptr<BufferQueueProducer> bqp = static_cast<BufferQueueProducer*>(cs->producer_.GetRefPtr());
ASSERT_EQ(bqp->bufferQueue_->queueSize_, 2u);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 2u);
SurfaceError ret = surface->SetQueueSize(1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
ret = surface->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
}
HWTEST_F(LocalProducerSurfaceTest, ReqRel, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int releaseFence;
SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, g_requestConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = surface->ReleaseBuffer(buffer, -1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ret = surface->CancelBuffer(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(LocalProducerSurfaceTest, UserData, testing::ext::TestSize.Level0)
{
SurfaceError ret;
std::string strs[SURFACE_MAX_USER_DATA_COUNT];
constexpr int32_t stringLengthMax = 32;
char str[stringLengthMax] = {};
for (int i = 0; i < SURFACE_MAX_USER_DATA_COUNT; i++) {
auto secRet = snprintf_s(str, sizeof(str), sizeof(str) - 1, "%d", i);
ASSERT_GT(secRet, 0);
strs[i] = str;
ret = surface->SetUserData(strs[i], "magic");
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
ret = surface->SetUserData("-1", "error");
ASSERT_NE(ret, SURFACE_ERROR_OK);
std::string retStr;
for (int i = 0; i < SURFACE_MAX_USER_DATA_COUNT; i++) {
retStr = surface->GetUserData(strs[i]);
ASSERT_EQ(retStr, "magic");
}
}
HWTEST_F(LocalProducerSurfaceTest, RegisterConsumerListener, testing::ext::TestSize.Level0)
{
class TestConsumerListener : public IBufferConsumerListener {
public:
void OnBufferAvailable() override {}
};
sptr<IBufferConsumerListener> listener = new TestConsumerListener();
SurfaceError ret = surface->RegisterConsumerListener(listener);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_PRODUCER_SURFACE_LOCAL_PRODUCER_SURFACE_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_PRODUCER_SURFACE_LOCAL_PRODUCER_SURFACE_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_PRODUCER_SURFACE_LOCAL_PRODUCER_SURFACE_TEST_H

View File

@ -0,0 +1,33 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_local_surface_buffer_impl_test {{{
ohos_unittest("surface_local_surface_buffer_impl_test") {
module_out_path = "graphic_standard/surface"
sources = [ "local_surface_buffer_impl_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest surface_local_surface_buffer_impl_test }}}
group("test") {
testonly = true
deps = [ ":surface_local_surface_buffer_impl_test" ]
}

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "local_surface_buffer_impl_test.h"
#include <display_type.h>
#include <gtest/gtest.h>
#include <surface_type.h>
#include "buffer_manager.h"
#include "environments.h"
#include "surface_buffer_impl.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
static sptr<SurfaceBufferImpl> buffer;
static int32_t val32;
static int64_t val64;
class LocalSurfaceBufferImplTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
buffer = nullptr;
val32 = 0;
val64 = 0;
}
static void TearDownTestCase(void)
{
buffer = nullptr;
}
};
HWTEST_F(LocalSurfaceBufferImplTest, NewSeqIncrease, testing::ext::TestSize.Level0)
{
buffer = new SurfaceBufferImpl();
int oldSeq = buffer->GetSeqNum();
buffer = new SurfaceBufferImpl();
ASSERT_EQ(oldSeq + 1, buffer->GetSeqNum());
}
HWTEST_F(LocalSurfaceBufferImplTest, NewState, testing::ext::TestSize.Level0)
{
ASSERT_EQ(buffer->GetBufferHandle(), nullptr);
ASSERT_EQ(buffer->GetVirAddr(), nullptr);
ASSERT_EQ(buffer->GetFileDescriptor(), -1);
ASSERT_EQ(buffer->GetSize(), 0u);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter32Positive, testing::ext::TestSize.Level0)
{
SurfaceError ret;
ret = buffer->SetInt32(0, 0x7fffffff);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = buffer->GetInt32(0, val32);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val32, 0x7fffffff);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter32Nagetive, testing::ext::TestSize.Level0)
{
SurfaceError ret;
ret = buffer->SetInt32(0, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = buffer->GetInt32(0, val32);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val32, -1);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter64Positive, testing::ext::TestSize.Level0)
{
SurfaceError ret;
ret = buffer->SetInt64(1, 0x7fffffffffLL);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = buffer->GetInt64(1, val64);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val64, 0x7fffffffffLL);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter64Negative, testing::ext::TestSize.Level0)
{
SurfaceError ret;
ret = buffer->SetInt64(1, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = buffer->GetInt64(1, val64);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val64, -1);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter32As64, testing::ext::TestSize.Level0)
{
SurfaceError ret;
val64 = 0x123;
ret = buffer->GetInt64(0, val64);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val64, 0x123);
}
HWTEST_F(LocalSurfaceBufferImplTest, GetterSetter64As32, testing::ext::TestSize.Level0)
{
SurfaceError ret;
val32 = 0x456;
ret = buffer->GetInt32(1, val32);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(val32, 0x456);
}
HWTEST_F(LocalSurfaceBufferImplTest, NormalState, testing::ext::TestSize.Level0)
{
ASSERT_EQ(buffer->GetBufferHandle(), nullptr);
SurfaceError ret = BufferManager::GetInstance()->Alloc(g_requestConfig, buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer->GetVirAddr(), nullptr);
ASSERT_NE(buffer->GetFileDescriptor(), -1);
ASSERT_NE(buffer->GetSize(), 0u);
ASSERT_NE(buffer->GetBufferHandle(), nullptr);
ret = BufferManager::GetInstance()->Free(buffer);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_SURFACE_BUFFER_IMPL_LOCAL_SURFACE_BUFFER_IMPL_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_SURFACE_BUFFER_IMPL_LOCAL_SURFACE_BUFFER_IMPL_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_LOCAL_SURFACE_BUFFER_IMPL_LOCAL_SURFACE_BUFFER_IMPL_TEST_H

View File

@ -0,0 +1,23 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
group("test") {
testonly = true
deps = [
"buffer_client_producer:test",
"buffer_queue_producer:test",
]
}

View File

@ -0,0 +1,36 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_remote_buffer_client_producer_test {{{
ohos_unittest("surface_remote_buffer_client_producer_test") {
module_out_path = "graphic_standard/surface"
sources = [ "remote_buffer_client_producer_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
}
## UnitTest surface_remote_buffer_client_producer_test }}}
group("test") {
testonly = true
deps = [ ":surface_remote_buffer_client_producer_test" ]
}

View File

@ -0,0 +1,261 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remote_buffer_client_producer_test.h"
#include <vector>
#include <display_type.h>
#include <gtest/gtest.h>
#include <iservice_registry.h>
#include <surface_type.h>
#include <sys/wait.h>
#include <unistd.h>
#include "buffer_client_producer.h"
#include "buffer_queue.h"
#include "buffer_queue_producer.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
sptr<IRemoteObject> robj;
sptr<IBufferProducer> bp;
std::vector<int32_t> deletingBuffers;
pid_t pid;
int pipeFd[2];
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class RemoteBufferClientProducerTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
pipe(pipeFd);
pid = fork();
if (pid < 0) {
exit(1);
}
if (pid == 0) {
sptr<BufferQueue> bq = new BufferQueue();
ASSERT_NE(bq, nullptr);
sptr<BufferQueueProducer> bqp = new BufferQueueProducer(bq);
ASSERT_NE(bqp, nullptr);
bq->Init();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
bq->RegisterConsumerListener(listener);
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sm->AddSystemAbility(IPC_QUEUE_SAID, bqp);
char buf[10] = "start";
write(pipeFd[1], buf, sizeof(buf));
sleep(0);
read(pipeFd[0], buf, sizeof(buf));
sm->RemoveSystemAbility(IPC_QUEUE_SAID);
exit(0);
}
char buf[10];
read(pipeFd[0], buf, sizeof(buf));
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
robj = sm->GetSystemAbility(IPC_QUEUE_SAID);
bp = iface_cast<IBufferProducer>(robj);
}
static void TearDownTestCase(void)
{
bp = nullptr;
robj = nullptr;
char buf[10] = "over";
write(pipeFd[1], buf, sizeof(buf));
waitpid(pid, nullptr, 0);
}
};
HWTEST_F(RemoteBufferClientProducerTest, IsProxy, testing::ext::TestSize.Level0)
{
ASSERT_TRUE(robj->IsProxyObject());
}
HWTEST_F(RemoteBufferClientProducerTest, QueueSize, testing::ext::TestSize.Level0)
{
ASSERT_EQ(bp->GetQueueSize(), (uint32_t)SURFACE_DEFAULT_QUEUE_SIZE);
SurfaceError ret = bp->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bp->GetQueueSize(), 2u);
}
HWTEST_F(RemoteBufferClientProducerTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer, nullptr);
ret = bp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferClientProducerTest, ReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer, nullptr);
ret = bp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferClientProducerTest, ReqReqReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer1;
sptr<SurfaceBuffer> buffer2;
sptr<SurfaceBuffer> buffer3;
int32_t releaseFence;
int32_t sequence1;
int32_t sequence2;
int32_t sequence3;
SurfaceError ret;
ret = bp->RequestBuffer(sequence1, buffer1, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer1, nullptr);
ret = bp->RequestBuffer(sequence2, buffer2, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer2, nullptr);
ret = bp->RequestBuffer(sequence3, buffer3, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer3, nullptr);
ret = bp->CancelBuffer(sequence1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence3);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferClientProducerTest, SetQueueSizeDeleting, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
sptr<BufferClientProducer> bcp = static_cast<BufferClientProducer*>(bp.GetRefPtr());
SurfaceError ret = bp->SetQueueSize(1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer, nullptr);
ret = bp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferClientProducerTest, ReqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferClientProducerTest, ReqFluFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_CLIENT_PRODUCER_REMOTE_BUFFER_CLIENT_PRODUCER_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_CLIENT_PRODUCER_REMOTE_BUFFER_CLIENT_PRODUCER_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_CLIENT_PRODUCER_REMOTE_BUFFER_CLIENT_PRODUCER_TEST_H

View File

@ -0,0 +1,36 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
## UnitTest surface_remote_buffer_queue_producer_test {{{
ohos_unittest("surface_remote_buffer_queue_producer_test") {
module_out_path = "graphic_standard/surface"
sources = [ "remote_buffer_queue_producer_test.cpp" ]
deps = [ "//foundation/graphic/standard/frameworks/surface/test/unittest:surface_test_common" ]
external_deps = [
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
}
## UnitTest surface_remote_buffer_queue_producer_test }}}
group("test") {
testonly = true
deps = [ ":surface_remote_buffer_queue_producer_test" ]
}

View File

@ -0,0 +1,259 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remote_buffer_queue_producer_test.h"
#include <vector>
#include <display_type.h>
#include <gtest/gtest.h>
#include <iservice_registry.h>
#include <surface_type.h>
#include "buffer_queue_producer.h"
#include "environments.h"
using namespace OHOS;
namespace {
BufferRequestConfig g_requestConfig = {
.width = 1920,
.height = 1080,
.strideAlignment = 8,
.format = PIXEL_FMT_RGBA_8888,
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
.timeout = 0,
};
BufferFlushConfig g_flushConfig = {
.damage = {
.x = 0,
.y = 0,
.w = 1920,
.h = 1080
},
.timestamp = 0
};
static int64_t timestamp;
static Rect damage;
static sptr<IRemoteObject> robj;
static sptr<IBufferProducer> bp;
static sptr<BufferQueue> bq;
static sptr<BufferQueueProducer> bqp;
static std::vector<int32_t> deletingBuffers;
class BufferConsumerListener: public IBufferConsumerListener {
public:
BufferConsumerListener()
{
}
~BufferConsumerListener()
{
}
void OnBufferAvailable()
{
}
};
class RemoteBufferQueueProducerTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
bq = new BufferQueue();
bqp = new BufferQueueProducer(bq);
bq->Init();
sptr<IBufferConsumerListener> listener = new BufferConsumerListener();
bq->RegisterConsumerListener(listener);
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sm->AddSystemAbility(IPC_QUEUE_SAID, bqp);
robj = sm->GetSystemAbility(IPC_QUEUE_SAID);
bp = iface_cast<IBufferProducer>(robj);
}
static void TearDownTestCase(void)
{
bp = nullptr;
robj = nullptr;
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sm->RemoveSystemAbility(IPC_QUEUE_SAID);
bqp = nullptr;
bq = nullptr;
}
};
HWTEST_F(RemoteBufferQueueProducerTest, IsProxy, testing::ext::TestSize.Level0)
{
ASSERT_FALSE(robj->IsProxyObject());
}
HWTEST_F(RemoteBufferQueueProducerTest, QueueSize, testing::ext::TestSize.Level0)
{
SurfaceError ret = bp->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->SetQueueSize(SURFACE_MAX_QUEUE_SIZE + 1);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bp->GetQueueSize(), 2u);
}
HWTEST_F(RemoteBufferQueueProducerTest, ReqCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferQueueProducerTest, ReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence);
ASSERT_NE(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferQueueProducerTest, ReqReqReqCanCan, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer1;
sptr<SurfaceBuffer> buffer2;
sptr<SurfaceBuffer> buffer3;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence1;
int32_t sequence2;
int32_t sequence3;
SurfaceError ret;
ret = bp->RequestBuffer(sequence1, buffer1, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer1, nullptr);
ret = bp->RequestBuffer(sequence2, buffer2, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_NE(buffer2, nullptr);
ret = bp->RequestBuffer(sequence3, buffer3, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_NE(ret, SURFACE_ERROR_OK);
ASSERT_EQ(buffer3, nullptr);
ret = bp->CancelBuffer(sequence1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->CancelBuffer(sequence3);
ASSERT_NE(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer1.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferQueueProducerTest, SetQueueSizeDeleting, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
sptr<BufferQueueProducer> bqp = static_cast<BufferQueueProducer*>(bp.GetRefPtr());
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 2u);
SurfaceError ret = bp->SetQueueSize(1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
ret = bp->SetQueueSize(2);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ASSERT_EQ(bqp->bufferQueue_->freeList_.size(), 1u);
}
HWTEST_F(RemoteBufferQueueProducerTest, ReqFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(bufferImpl, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
HWTEST_F(RemoteBufferQueueProducerTest, ReqFluFlu, testing::ext::TestSize.Level0)
{
sptr<SurfaceBuffer> buffer;
int32_t releaseFence;
int32_t flushFence;
int32_t sequence;
SurfaceError ret = bp->RequestBuffer(sequence, buffer, releaseFence, g_requestConfig, deletingBuffers);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bp->FlushBuffer(sequence, -1, g_flushConfig);
ASSERT_NE(ret, SURFACE_ERROR_OK);
sptr<SurfaceBufferImpl> bufferImpl = static_cast<SurfaceBufferImpl*>(buffer.GetRefPtr());
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->ReleaseBuffer(bufferImpl, -1);
ASSERT_EQ(ret, SURFACE_ERROR_OK);
ret = bq->AcquireBuffer(bufferImpl, flushFence, timestamp, damage);
ASSERT_NE(ret, SURFACE_ERROR_OK);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_QUEUE_PRODUCER_REMOTE_BUFFER_QUEUE_PRODUCER_TEST_H
#define FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_QUEUE_PRODUCER_REMOTE_BUFFER_QUEUE_PRODUCER_TEST_H
#endif // FRAMEWORKS_SURFACE_TEST_UNITTEST_REMOTE_BUFFER_QUEUE_PRODUCER_REMOTE_BUFFER_QUEUE_PRODUCER_TEST_H

121
frameworks/vsync/BUILD.gn Executable file
View File

@ -0,0 +1,121 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Build libvsync_client.so {{{
config("libvsync_client_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("libvsync_client_public_config") {
include_dirs = [
"//foundation/graphic/standard/interfaces/innerkits/vsync",
"//foundation/graphic/standard/interfaces/innerkits/vsync/client",
]
}
ohos_shared_library("libvsync_client") {
sources = [
"src/vsync_callback_stub.cpp",
"src/vsync_helper.cpp",
"src/vsync_helper_impl.cpp",
"src/vsync_manager_proxy.cpp",
]
configs = [ ":libvsync_client_config" ]
public_configs = [ ":libvsync_client_public_config" ]
deps = [
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [ "ipc:ipc_core" ]
public_deps = [
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//utils/native/base:utils",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build libvsync_client.so }}}
## Build libvsync_server.a {{{
config("libvsync_server_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("libvsync_server_public_config") {
include_dirs = [
"//foundation/graphic/standard/interfaces/innerkits/vsync",
"//foundation/graphic/standard/interfaces/innerkits/vsync/server",
]
}
ohos_static_library("libvsync_server") {
sources = [
"src/vsync_callback_proxy.cpp",
"src/vsync_manager.cpp",
"src/vsync_module.cpp",
"src/vsync_module_impl.cpp",
]
configs = [ ":libvsync_server_config" ]
public_configs = [ ":libvsync_server_public_config" ]
deps = [ "//third_party/libdrm:libdrm" ]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
public_deps = []
}
## Build libvsync_server.a }}}
group("test") {
testonly = true
deps = [ "test:test" ]
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_CALLBACK_H
#define FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_CALLBACK_H
#include <iremote_broker.h>
namespace OHOS {
class IVsyncCallback : public IRemoteBroker {
public:
enum {
IVSYNC_CALLBACK_ON_VSYNC,
};
virtual void OnVsync(int64_t timestamp) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IVsyncCallback");
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_CALLBACK_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_MANAGER_H
#define FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_MANAGER_H
#include <iremote_broker.h>
#include "vsync_type.h"
#include "ivsync_callback.h"
namespace OHOS {
class IVsyncManager : public IRemoteBroker {
public:
enum {
IVSYNC_MANAGER_LISTEN_NEXT_VSYNC,
};
virtual VsyncError ListenNextVsync(sptr<IVsyncCallback>& cb) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IVsyncManager");
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_IVSYNC_MANAGER_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_PROXY_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_PROXY_H
#include "ivsync_callback.h"
#include <iremote_proxy.h>
namespace OHOS {
class VsyncCallbackProxy : public IRemoteProxy<IVsyncCallback> {
public:
VsyncCallbackProxy(const sptr<IRemoteObject>& impl);
virtual ~VsyncCallbackProxy();
void OnVsync(int64_t timestamp) override;
private:
static inline BrokerDelegator<VsyncCallbackProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_PROXY_H

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_STUB_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_STUB_H
#include "ivsync_callback.h"
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
namespace OHOS {
class VsyncCallbackStub : public IRemoteStub<IVsyncCallback> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_CALLBACK_STUB_H

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_HELPER_IMPL_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_HELPER_IMPL_H
#include <mutex>
#include <queue>
#include <memory>
#include <vsync_helper.h>
#include "ivsync_manager.h"
#include "vsync_manager_proxy.h"
#include "vsync_callback_stub.h"
namespace OHOS {
namespace {
class VsyncCallback;
}
class VsyncHelperImpl : public VsyncHelper {
friend class VsyncCallback;
public:
static sptr<VsyncHelperImpl> Current();
VsyncHelperImpl(std::shared_ptr<AppExecFwk::EventHandler>& handler);
virtual ~VsyncHelperImpl();
VsyncError RequestFrameCallback(struct FrameCallback& cb);
protected:
virtual VsyncError InitSA();
VsyncError InitSA(int32_t vsyncSystemAbilityId);
private:
VsyncError Init();
void DispatchFrameCallback(int64_t timestamp);
void RequestNextVsync();
bool isVsyncRequested = false;
std::mutex callbacks_mutex_;
std::priority_queue<struct FrameCallback> callbacks_;
std::shared_ptr<AppExecFwk::EventHandler> handler_;
sptr<IVsyncManager> service_;
static thread_local sptr<VsyncHelperImpl> currentHelper;
};
namespace {
class VsyncCallback : public VsyncCallbackStub {
public:
VsyncCallback(sptr<VsyncHelperImpl>& helper);
virtual ~VsyncCallback();
void OnVsync(int64_t timestamp) override;
private:
sptr<VsyncHelperImpl> helper_;
};
}
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_HELPER_IMPL_H

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_LOG_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_LOG_H
#include <hilog/log.h>
#ifdef __aarch64__
#define VPUBI64 "%{public}ld"
#define VPUBSize "%{public}lu"
#define VPUBU64 "%{public}lu"
#else
#define VPUBI64 "%{public}lld"
#define VPUBSize "%{public}u"
#define VPUBU64 "%{public}llu"
#endif
#define __VLOG(func, fmt, ...) \
func(LABEL, "%{public}s: " fmt "\033[0m", __func__, ##__VA_ARGS__)
#define VLOGD(fmt, ...) __VLOG(::OHOS::HiviewDFX::HiLog::Debug, "\033[0m" fmt, ##__VA_ARGS__)
#define VLOGI(fmt, ...) __VLOG(::OHOS::HiviewDFX::HiLog::Info, "\033[36m" fmt, ##__VA_ARGS__)
#define VLOGW(fmt, ...) __VLOG(::OHOS::HiviewDFX::HiLog::Warn, "\033[1;33m" fmt, ##__VA_ARGS__)
#define VLOGE(fmt, ...) __VLOG(::OHOS::HiviewDFX::HiLog::Error, "\033[1;31m" fmt, ##__VA_ARGS__)
#define VLOG_SUCCESS(fmt, ...) VLOGI("Success, Way: " fmt, ##__VA_ARGS__);
#define VLOG_FAILURE(fmt, ...) VLOGE("Failure, Reason: " fmt, ##__VA_ARGS__);
#define VLOG_FAILURE_NO(vsync_error) VLOG_FAILURE("%{public}s", VsyncErrorStr(vsync_error).c_str())
#define VLOG_FAILURE_RET(vsync_error) \
do { \
VLOG_FAILURE_NO(vsync_error); \
return vsync_error; \
} while (0)
#define VLOG_FAILURE_API(api, ret) VLOG_FAILURE(#api " failed with %{public}s", VsyncErrorStr(ret).c_str())
#define VLOG_ERROR(errno, fmt, ...) \
VLOGE(fmt ", means %{public}s", ##__VA_ARGS__, strerror(errno))
#define VLOG_ERROR_API(ret, api) \
VLOG_ERROR(ret, #api " failed with %{public}d", ret)
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_LOG_H

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_H
#include <list>
#include <mutex>
#include "ivsync_manager.h"
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
namespace OHOS {
class VsyncManager : public IRemoteStub<IVsyncManager> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
VsyncError ListenNextVsync(sptr<IVsyncCallback>& cb) override;
void Callback(int64_t timestamp);
void CheckVsyncRequest();
void StopCheck();
private:
std::list<sptr<IVsyncCallback>> callbacks;
std::mutex callbacks_mutex;
std::condition_variable condition_;
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_PROXY_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_PROXY_H
#include "ivsync_manager.h"
#include <iremote_proxy.h>
namespace OHOS {
class VsyncManagerProxy : public IRemoteProxy<IVsyncManager> {
public:
VsyncManagerProxy(const sptr<IRemoteObject>& impl);
virtual ~VsyncManagerProxy();
VsyncError ListenNextVsync(sptr<IVsyncCallback>& cb) override;
private:
static inline BrokerDelegator<VsyncManagerProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MANAGER_PROXY_H

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MODULE_IMPL_H
#define FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MODULE_IMPL_H
#include <thread>
#include <vsync_module.h>
#include "vsync_type.h"
#include "vsync_manager.h"
namespace OHOS {
class VsyncModuleImpl : public VsyncModule {
public:
static sptr<VsyncModuleImpl> GetInstance()
{
static sptr<VsyncModuleImpl> ptr = new VsyncModuleImpl();
return ptr;
}
VsyncError Start();
VsyncError Stop();
protected:
virtual VsyncError InitSA();
VsyncError InitSA(int32_t vsyncSystemAbilityId);
private:
VsyncModuleImpl();
virtual ~VsyncModuleImpl();
void VsyncMainThread();
bool RegisterSystemAbility();
void UnregisterSystemAbility();
int64_t WaitNextVBlank();
int32_t drmFd_;
std::unique_ptr<std::thread> vsyncThread_;
bool vsyncThreadRunning_;
int32_t vsyncSystemAbilityId_;
bool isRegisterSA_;
sptr<VsyncManager> vsyncManager_;
};
} // namespace OHOS
#endif // FRAMEWORKS_VSYNC_INCLUDE_VSYNC_MODULE_IMPL_H

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_callback_proxy.h"
#include "vsync_log.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncCallbackProxy" };
}
VsyncCallbackProxy::VsyncCallbackProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IVsyncCallback>(impl)
{
}
VsyncCallbackProxy::~VsyncCallbackProxy()
{
}
void VsyncCallbackProxy::OnVsync(int64_t timestamp)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
VLOGE("write interface token failed");
}
bool retval = arg.WriteInt64(timestamp);
if (!retval) {
VLOGE("arg.WriteInt64 failed");
return;
}
int res = Remote()->SendRequest(IVSYNC_CALLBACK_ON_VSYNC, arg, ret, opt);
if (res) {
VLOG_ERROR_API(res, SendRequest);
}
}
} // namespace OHOS

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_callback_stub.h"
#include "vsync_log.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncCallbackStub" };
}
int32_t VsyncCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return ERR_INVALID_STATE;
}
switch (code) {
case IVSYNC_CALLBACK_ON_VSYNC: {
int64_t timestamp;
bool ret = data.ReadInt64(timestamp);
if (!ret) {
VLOG_FAILURE("need param");
return 1;
}
OnVsync(timestamp);
} break;
default: {
VLOG_FAILURE("code %{public}d cannot process", code);
return 1;
} break;
}
return 0;
}
} // namespace OHOS

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vsync_helper.h>
#include "vsync_helper_impl.h"
namespace OHOS {
sptr<VsyncHelper> VsyncHelper::Current()
{
return VsyncHelperImpl::Current();
}
sptr<VsyncHelper> VsyncHelper::FromHandler(std::shared_ptr<AppExecFwk::EventHandler>& handler)
{
sptr<VsyncHelper> helper = new VsyncHelperImpl(handler);
return helper;
}
} // namespace OHOS

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_helper_impl.h"
#include <sys/time.h>
#include <iservice_registry.h>
#include <system_ability_definition.h>
#include "vsync_log.h"
#include "vsync_type.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncHelperImpl" };
constexpr int SEC_TO_USEC = 1000000;
}
thread_local sptr<VsyncHelperImpl> VsyncHelperImpl::currentHelper;
static int64_t GetNowTime()
{
struct timeval tv = {};
gettimeofday(&tv, nullptr);
return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * SEC_TO_USEC;
}
VsyncCallback::VsyncCallback(sptr<VsyncHelperImpl>& helper) : helper_(helper)
{
}
VsyncCallback::~VsyncCallback()
{
}
void VsyncCallback::OnVsync(int64_t timestamp)
{
if (helper_) {
helper_->DispatchFrameCallback(timestamp);
}
}
sptr<VsyncHelperImpl> VsyncHelperImpl::Current()
{
if (currentHelper == nullptr) {
auto currentRunner = AppExecFwk::EventRunner::Current();
if (currentRunner == nullptr) {
VLOG_FAILURE("AppExecFwk::EventRunner::Current() return nullptr");
return nullptr;
}
std::shared_ptr<AppExecFwk::EventHandler> handler =
std::make_shared<AppExecFwk::EventHandler>(currentRunner);
currentHelper = new VsyncHelperImpl(handler);
VLOG_SUCCESS("new VsyncHelperImpl");
}
return currentHelper;
}
VsyncHelperImpl::VsyncHelperImpl(std::shared_ptr<AppExecFwk::EventHandler>& handler)
{
handler_ = handler;
}
VsyncHelperImpl::~VsyncHelperImpl()
{
}
VsyncError VsyncHelperImpl::Init()
{
return InitSA();
}
VsyncError VsyncHelperImpl::InitSA()
{
return InitSA(VSYNC_MANAGER_ID);
}
VsyncError VsyncHelperImpl::InitSA(int32_t systemAbilityId)
{
if (service_ != nullptr) {
VLOG_SUCCESS("service_ != nullptr");
return VSYNC_ERROR_OK;
}
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sm == nullptr) {
VLOG_FAILURE_RET(VSYNC_ERROR_SAMGR);
}
auto remoteObject = sm->GetSystemAbility(systemAbilityId);
if (remoteObject == nullptr) {
VLOG_FAILURE_RET(VSYNC_ERROR_SERVICE_NOT_FOUND);
}
service_ = iface_cast<IVsyncManager>(remoteObject);
if (service_ == nullptr) {
VLOG_FAILURE_RET(VSYNC_ERROR_PROXY_NOT_INCLUDE);
}
VLOG_SUCCESS("service_ = iface_cast");
return VSYNC_ERROR_OK;
}
VsyncError VsyncHelperImpl::RequestFrameCallback(struct FrameCallback &cb)
{
if (cb.callback_ == nullptr) {
VLOG_FAILURE_RET(VSYNC_ERROR_NULLPTR);
}
if (service_ == nullptr) {
VsyncError ret = Init();
if (ret != VSYNC_ERROR_OK) {
return ret;
}
}
int64_t delayTime = cb.timestamp_;
cb.timestamp_ += GetNowTime();
{
std::lock_guard<std::mutex> lockGuard(callbacks_mutex_);
callbacks_.push(cb);
}
if (delayTime <= 0 && handler_->GetEventRunner()->IsCurrentRunnerThread()) {
RequestNextVsync();
VLOG_SUCCESS("RequestNextVsync time: " VPUBI64, delayTime);
} else {
handler_->PostTask([this]() { RequestNextVsync(); }, "FrameCallback", delayTime);
VLOG_SUCCESS("PostTask time: " VPUBI64, delayTime);
}
return VSYNC_ERROR_OK;
}
void VsyncHelperImpl::DispatchFrameCallback(int64_t timestamp)
{
handler_->PostTask([this, timestamp]() {
isVsyncRequested = false;
int64_t now = GetNowTime();
VLOGI("DispatchFrameCallback, time: " VPUBI64 ", timestamp: " VPUBI64, now, timestamp);
std::list<struct FrameCallback> frameCallbacks;
{
std::lock_guard<std::mutex> lockGuard(callbacks_mutex_);
while (callbacks_.empty() != true) {
if (callbacks_.top().timestamp_ <= now) {
frameCallbacks.push_back(callbacks_.top());
callbacks_.pop();
} else {
break;
}
}
}
for (auto it = frameCallbacks.begin(); it != frameCallbacks.end(); it++) {
it->callback_(timestamp, it->userdata_);
}
});
}
void VsyncHelperImpl::RequestNextVsync()
{
struct FrameCallback cb;
{
std::lock_guard<std::mutex> lockGuard(callbacks_mutex_);
if (isVsyncRequested || callbacks_.empty()) {
return;
}
cb = callbacks_.top();
}
if (cb.timestamp_ <= GetNowTime()) {
sptr<VsyncHelperImpl> helper = this;
sptr<IVsyncCallback> ivcb = new VsyncCallback(helper);
VsyncError ret = service_->ListenNextVsync(ivcb);
if (ret == VSYNC_ERROR_OK) {
isVsyncRequested = true;
VLOG_SUCCESS("ListenNextVsync");
} else {
VLOG_FAILURE_API(ListenNextVsync, ret);
}
}
}
} // namespace OHOS

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_manager.h"
#include "vsync_callback_proxy.h"
#include "vsync_log.h"
#define REMOTE_RETURN(reply, vsync_error) \
reply.WriteInt32(vsync_error); \
if (vsync_error != VSYNC_ERROR_OK) { \
VLOG_FAILURE_NO(vsync_error); \
} \
break
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncManager" };
}
int32_t VsyncManager::OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return ERR_INVALID_STATE;
}
switch (code) {
case IVSYNC_MANAGER_LISTEN_NEXT_VSYNC: {
auto remoteObject = data.ReadRemoteObject();
if (remoteObject == nullptr) {
REMOTE_RETURN(reply, VSYNC_ERROR_NULLPTR);
}
auto cb = iface_cast<IVsyncCallback>(remoteObject);
VsyncError ret = ListenNextVsync(cb);
REMOTE_RETURN(reply, ret);
} break;
default: {
VLOG_FAILURE("code %{public}d cannot process", code);
return 1;
} break;
}
return 0;
}
VsyncError VsyncManager::ListenNextVsync(sptr<IVsyncCallback>& cb)
{
if (cb == nullptr) {
VLOG_FAILURE_NO(VSYNC_ERROR_NULLPTR);
return VSYNC_ERROR_NULLPTR;
}
std::unique_lock<std::mutex> lockGuard(callbacks_mutex);
callbacks.push_back(cb);
condition_.notify_all();
return VSYNC_ERROR_OK;
}
void VsyncManager::Callback(int64_t timestamp)
{
std::unique_lock<std::mutex> lockGuard(callbacks_mutex);
for (auto it = callbacks.begin(); it != callbacks.end(); it++) {
(*it)->OnVsync(timestamp);
}
callbacks.clear();
}
void VsyncManager::CheckVsyncRequest()
{
std::unique_lock<std::mutex> lockGuard(callbacks_mutex);
while (callbacks.empty()) {
condition_.wait(lockGuard);
}
}
void VsyncManager::StopCheck()
{
callbacks.push_back(nullptr);
condition_.notify_all();
}
} // namespace OHOS

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <message_option.h>
#include <message_parcel.h>
#include "vsync_log.h"
#include "vsync_manager_proxy.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncManagerProxy" };
}
VsyncManagerProxy::VsyncManagerProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IVsyncManager>(impl)
{
VLOGI("DEBUG VsyncManagerProxy");
}
VsyncManagerProxy::~VsyncManagerProxy()
{
VLOGI("DEBUG ~VsyncManagerProxy");
}
VsyncError VsyncManagerProxy::ListenNextVsync(sptr<IVsyncCallback>& cb)
{
if (cb == nullptr) {
VLOG_FAILURE_NO(VSYNC_ERROR_NULLPTR);
return VSYNC_ERROR_NULLPTR;
}
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
VLOGE("write interface token failed");
}
arg.WriteRemoteObject(cb->AsObject());
int result = Remote()->SendRequest(IVSYNC_MANAGER_LISTEN_NEXT_VSYNC, arg, ret, opt);
if (result) {
VLOG_ERROR_API(result, SendRequest);
return VSYNC_ERROR_BINDER_ERROR;
}
VsyncError err = (VsyncError)ret.ReadInt32();
if (err != VSYNC_ERROR_OK) {
VLOG_FAILURE_NO(err);
}
return err;
}
} // namespace OHOS

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vsync_module.h>
#include "vsync_module_impl.h"
namespace OHOS {
sptr<VsyncModule> VsyncModule::GetInstance()
{
return VsyncModuleImpl::GetInstance();
}
} // namespace OHOS

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_module_impl.h"
#include <unistd.h>
#include <xf86drm.h>
#include <chrono>
#include <iservice_registry.h>
#include <system_ability_definition.h>
#include "vsync_log.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncModuleImpl" };
constexpr int USLEEP_TIME = 100 * 1000;
constexpr int RETRY_TIMES = 5;
}
int64_t VsyncModuleImpl::WaitNextVBlank()
{
drmVBlank vblank = {
.request = drmVBlankReq {
.type = DRM_VBLANK_RELATIVE,
.sequence = 1,
}
};
int ret = drmWaitVBlank(drmFd_, &vblank);
if (ret != 0) {
VLOG_ERROR_API(errno, drmWaitVBlank);
return -1;
}
// uptime
auto now = std::chrono::steady_clock::now().time_since_epoch();
return (int64_t)std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
}
void VsyncModuleImpl::VsyncMainThread()
{
while (vsyncThreadRunning_) {
vsyncManager_->CheckVsyncRequest();
if (!vsyncThreadRunning_) {
break;
}
int64_t timestamp = WaitNextVBlank();
if (timestamp < 0) {
continue;
}
vsyncManager_->Callback(timestamp);
}
}
bool VsyncModuleImpl::RegisterSystemAbility()
{
if (isRegisterSA_) {
return true;
}
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sm) {
sm->AddSystemAbility(vsyncSystemAbilityId_, vsyncManager_);
isRegisterSA_ = true;
}
return isRegisterSA_;
}
void VsyncModuleImpl::UnregisterSystemAbility()
{
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sm) {
sm->RemoveSystemAbility(vsyncSystemAbilityId_);
isRegisterSA_ = false;
}
}
VsyncModuleImpl::VsyncModuleImpl()
{
VLOGD("DEBUG VsyncModuleImpl");
drmFd_ = -1;
vsyncThread_ = nullptr;
vsyncThreadRunning_ = false;
vsyncSystemAbilityId_ = 0;
isRegisterSA_ = false;
vsyncManager_ = new VsyncManager();
}
VsyncModuleImpl::~VsyncModuleImpl()
{
VLOGD("DEBUG ~VsyncModuleImpl");
if (vsyncThreadRunning_) {
Stop();
}
if (isRegisterSA_) {
UnregisterSystemAbility();
}
}
VsyncError VsyncModuleImpl::Start()
{
VsyncError ret = InitSA();
if (ret != VSYNC_ERROR_OK) {
return ret;
}
drmFd_ = drmOpen(DRM_MODULE_NAME, nullptr);
if (drmFd_ < 0) {
VLOG_ERROR_API(errno, drmOpen);
return VSYNC_ERROR_API_FAILED;
}
VLOGD("drmOpen fd is %{public}d", drmFd_);
vsyncThreadRunning_ = true;
vsyncThread_ = std::make_unique<std::thread>([this]()->void {
VsyncMainThread();
});
return VSYNC_ERROR_OK;
}
VsyncError VsyncModuleImpl::Stop()
{
if (!vsyncThreadRunning_) {
return VSYNC_ERROR_INVALID_OPERATING;
}
vsyncThreadRunning_ = false;
vsyncManager_->StopCheck();
vsyncThread_->join();
vsyncThread_.reset();
int ret = drmClose(drmFd_);
if (ret) {
VLOG_ERROR_API(errno, drmClose);
return VSYNC_ERROR_API_FAILED;
}
drmFd_ = -1;
if (isRegisterSA_) {
UnregisterSystemAbility();
}
return VSYNC_ERROR_OK;
}
VsyncError VsyncModuleImpl::InitSA()
{
return InitSA(VSYNC_MANAGER_ID);
}
VsyncError VsyncModuleImpl::InitSA(int32_t vsyncSystemAbilityId)
{
vsyncSystemAbilityId_ = vsyncSystemAbilityId;
int tryCount = 0;
while (!RegisterSystemAbility()) {
if (tryCount++ >= RETRY_TIMES) {
VLOGE("RegisterSystemAbility failed after %{public}d tries!!!", RETRY_TIMES);
return VSYNC_ERROR_SERVICE_NOT_FOUND;
} else {
VLOGE("RegisterSystemAbility failed, try again:%{public}d", tryCount);
usleep(USLEEP_TIME);
}
}
return VSYNC_ERROR_OK;
}
} // namespace OHOS

View File

@ -0,0 +1,18 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("test") {
testonly = true
deps = [ "unittest:unittest" ]
}

View File

@ -0,0 +1,108 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
module_out_path = "graphic_standard/vsync"
group("unittest") {
testonly = true
deps = [
":vsync_helper_test",
":vsync_manager_remote_test",
":vsync_manager_test",
":vsync_module_test",
]
}
## UnitTest vsync_helper_test {{{
ohos_unittest("vsync_helper_test") {
module_out_path = module_out_path
sources = [ "vsync_helper_test.cpp" ]
deps = [ ":vsync_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest vsync_helper_test }}}
## UnitTest vsync_manager_test {{{
ohos_unittest("vsync_manager_test") {
module_out_path = module_out_path
sources = [ "vsync_manager_test.cpp" ]
deps = [ ":vsync_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest vsync_manager_test }}}
## UnitTest vsync_manager_remote_test {{{
ohos_unittest("vsync_manager_remote_test") {
module_out_path = module_out_path
sources = [ "vsync_manager_remote_test.cpp" ]
deps = [ ":vsync_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest vsync_manager_remote_test }}}
## UnitTest vsync_module_test {{{
ohos_unittest("vsync_module_test") {
module_out_path = module_out_path
sources = [ "vsync_module_test.cpp" ]
deps = [ ":vsync_test_common" ]
external_deps = [ "ipc:ipc_core" ]
}
## UnitTest vsync_module_test }}}
## Build vsync_test_common.a {{{
config("vsync_test_common_public_config") {
include_dirs = [
"//foundation/graphic/standard/frameworks/vsync/include",
"//utils/system/safwk/native/include",
"//utils/native/base/include",
]
cflags = [
"-Dprivate=public",
"-Dprotected=public",
]
}
ohos_static_library("vsync_test_common") {
public_configs = [ ":vsync_test_common_public_config" ]
public_deps = [
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/graphic/standard:libvsync_client",
"//foundation/graphic/standard:libvsync_server",
"//utils/native/base:utils",
]
external_deps = [ "ipc:ipc_core" ]
}
## Build vsync_test_common.a }}}

View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_helper_test.h"
#include <event_handler.h>
#include <gtest/gtest.h>
#include <system_ability_definition.h>
#include "vsync_helper_impl.h"
#include "vsync_module_impl.h"
#include "vsync_log.h"
using namespace OHOS;
#define SWITCH() \
do { \
usleep(MICROSECOND_SWITCH); \
sleep(0); \
} while (0)
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "VsyncHelperTest" };
} // namespace
class TestVsyncModule : public VsyncModuleImpl {
public:
static TestVsyncModule* GetInstance()
{
static TestVsyncModule m;
return &m;
}
virtual VsyncError InitSA() override
{
return VsyncModuleImpl::InitSA(VSYNC_MANAGER_TEST_ID);
}
private:
TestVsyncModule() = default;
~TestVsyncModule() = default;
};
class TestVsyncHelper : public VsyncHelperImpl {
public:
static sptr<VsyncHelperImpl> Current()
{
if (currentTestHelper == nullptr) {
auto currentRunner = AppExecFwk::EventRunner::Current();
if (currentRunner == nullptr) {
VLOG_FAILURE("AppExecFwk::EventRunner::Current() return nullptr");
return nullptr;
}
std::shared_ptr<AppExecFwk::EventHandler> handler =
std::make_shared<AppExecFwk::EventHandler>(currentRunner);
VLOG_SUCCESS("new TestVsyncHelper");
currentTestHelper = new TestVsyncHelper(handler);
}
return currentTestHelper;
}
explicit TestVsyncHelper(std::shared_ptr<AppExecFwk::EventHandler>& handler)
: VsyncHelperImpl(handler)
{
}
~TestVsyncHelper()
{
}
virtual VsyncError InitSA() override
{
return VsyncHelperImpl::InitSA(VSYNC_MANAGER_TEST_ID);
}
private:
static thread_local sptr<TestVsyncHelper> currentTestHelper;
};
thread_local sptr<TestVsyncHelper> TestVsyncHelper::currentTestHelper;
class GlobalData {
public:
static GlobalData *GetInstance()
{
static GlobalData data;
return &data;
}
sptr<TestVsyncHelper> helper_;
std::shared_ptr<AppExecFwk::EventRunner> runner_;
std::shared_ptr<AppExecFwk::EventHandler> handler_;
private:
GlobalData() = default;
~GlobalData() = default;
};
class VsyncHelperTest : public testing::Test {
public:
static void SetUpTestCase()
{
TestVsyncModule::GetInstance()->Start();
auto d = GlobalData::GetInstance();
d->runner_ = AppExecFwk::EventRunner::Create(true);
d->handler_ = std::make_shared<AppExecFwk::EventHandler>(d->runner_);
d->helper_ = new TestVsyncHelper(d->handler_);
}
static void TearDownTestCase()
{
GlobalData::GetInstance()->helper_ = nullptr;
TestVsyncModule::GetInstance()->Stop();
}
private:
static constexpr useconds_t MICROSECOND_SWITCH = 50 * 1000;
};
class TestVsyncCallback : public VsyncCallbackStub {
public:
explicit TestVsyncCallback(int &num) : num_(num)
{
}
~TestVsyncCallback()
{
}
void OnVsync(int64_t timestamp) override
{
num_++;
}
private:
int &num_;
};
namespace {
HWTEST_F(VsyncHelperTest, RequestFrameCallback, testing::ext::TestSize.Level0)
{
auto runner = AppExecFwk::EventRunner::Create(false);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask([&]() {
sptr<VsyncHelperImpl> helper = new TestVsyncHelper(handler);
static int num = 0;
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = &num,
.callback_ = [](int64_t timestamp, void* userdata) {
(*(int*)userdata)++;
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(helper->callbacks_.size(), 1u);
ret = helper->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(helper->callbacks_.size(), 2u);
ret = helper->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(helper->callbacks_.size(), 3u);
ASSERT_EQ(num, 0);
handler->PostTask([&]() {
ASSERT_EQ(num, 3);
handler->PostTask([&]() { runner->Stop(); });
});
});
}
HWTEST_F(VsyncHelperTest, EventHandler, testing::ext::TestSize.Level0)
{
auto runner = AppExecFwk::EventRunner::Create(false);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask([&]() {
static int num = 0;
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = &num,
.callback_ = [](int64_t timestamp, void* userdata) {
(*(int*)userdata)++;
},
};
VsyncError ret = GlobalData::GetInstance()->helper_->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(GlobalData::GetInstance()->helper_->callbacks_.size(), 1u);
ASSERT_EQ(num, 0);
handler->PostTask([&]() {
ASSERT_EQ(num, 1);
VsyncError ret = GlobalData::GetInstance()->helper_->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(GlobalData::GetInstance()->helper_->callbacks_.size(), 1u);
ASSERT_EQ(num, 1);
handler->PostTask([&]() {
ASSERT_EQ(num, 2);
});
});
});
}
HWTEST_F(VsyncHelperTest, CurrentWithNullptr, testing::ext::TestSize.Level0)
{
auto runner = AppExecFwk::EventRunner::Current();
ASSERT_EQ(runner, nullptr);
auto helper = VsyncHelper::Current();
ASSERT_EQ(helper, nullptr);
}
HWTEST_F(VsyncHelperTest, Current, testing::ext::TestSize.Level0)
{
int num = 0;
auto runner = AppExecFwk::EventRunner::Create(true);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask([&handler, &num]() {
auto runner = AppExecFwk::EventRunner::Current();
ASSERT_NE(runner, nullptr);
auto helper = TestVsyncHelper::Current();
ASSERT_NE(helper, nullptr);
struct FrameCallback cb = {
.timestamp_ = 0,
.userdata_ = &num,
.callback_ = [](int64_t timestamp, void* userdata) {
(*(int*)userdata)++;
},
};
VsyncError ret = helper->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(helper->callbacks_.size(), 1u);
ret = helper->RequestFrameCallback(cb);
ASSERT_EQ(ret, VSYNC_ERROR_OK);
ASSERT_EQ(helper->callbacks_.size(), 2u);
ASSERT_EQ(num, 0);
handler->PostTask([&num](){
ASSERT_EQ(num, 2);
}, MICROSECOND_SWITCH);
});
SWITCH();
}
} // namespace

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_HELPER_VSYNC_HELPER_TEST_H
#define FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_HELPER_VSYNC_HELPER_TEST_H
#endif // FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_HELPER_VSYNC_HELPER_TEST_H

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_manager_remote_test.h"
#include <sys/wait.h>
#include <unistd.h>
#include <gtest/gtest.h>
#include <iservice_registry.h>
#include <system_ability_definition.h>
#include "vsync_callback_stub.h"
#include "vsync_log.h"
#include "vsync_manager.h"
#include "vsync_manager_proxy.h"
using namespace OHOS;
class GlobalData {
public:
static GlobalData *GetInstance()
{
static GlobalData data;
return &data;
}
pid_t pid_;
int pipeFd_[2];
sptr<IVsyncManager> manager_;
sptr<IRemoteObject> robj;
private:
GlobalData() = default;
~GlobalData() = default;
};
class VsyncManagerRemoteTest : public testing::Test {
public:
static void SetUpTestCase()
{
pipe(GlobalData::GetInstance()->pipeFd_);
GlobalData::GetInstance()->pid_ = fork();
if (GlobalData::GetInstance()->pid_ < 0) {
exit(1);
}
if (GlobalData::GetInstance()->pid_ == 0) {
sptr<VsyncManager> remoteVsyncManager_ = new VsyncManager();
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sam->AddSystemAbility(VSYNC_MANAGER_TEST_ID, remoteVsyncManager_);
char buf[10] = {};
write(GlobalData::GetInstance()->pipeFd_[1], buf, sizeof(buf));
sleep(0);
read(GlobalData::GetInstance()->pipeFd_[0], buf, sizeof(buf));
sam->RemoveSystemAbility(VSYNC_MANAGER_TEST_ID);
close(GlobalData::GetInstance()->pipeFd_[0]);
close(GlobalData::GetInstance()->pipeFd_[1]);
exit(0);
}
char buf[10];
read(GlobalData::GetInstance()->pipeFd_[0], buf, sizeof(buf));
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
GlobalData::GetInstance()->robj = sam->GetSystemAbility(VSYNC_MANAGER_TEST_ID);
GlobalData::GetInstance()->manager_ = iface_cast<IVsyncManager>(GlobalData::GetInstance()->robj);
}
static void TearDownTestCase()
{
GlobalData::GetInstance()->manager_ = nullptr;
GlobalData::GetInstance()->robj = nullptr;
char buf[10] = {};
write(GlobalData::GetInstance()->pipeFd_[1], buf, sizeof(buf));
waitpid(GlobalData::GetInstance()->pid_, nullptr, 0);
close(GlobalData::GetInstance()->pipeFd_[0]);
close(GlobalData::GetInstance()->pipeFd_[1]);
}
};
class VsyncCallback : public VsyncCallbackStub {
public:
void OnVsync(int64_t timestamp)
{
isCall_ = true;
}
bool IsCall() const
{
return isCall_;
}
private:
bool isCall_ = false;
};
namespace {
HWTEST_F(VsyncManagerRemoteTest, IsProxy, testing::ext::TestSize.Level0)
{
ASSERT_NE(GlobalData::GetInstance()->manager_, nullptr);
ASSERT_NE(GlobalData::GetInstance()->manager_->AsObject(), nullptr);
ASSERT_TRUE(GlobalData::GetInstance()->manager_->AsObject()->IsProxyObject());
}
HWTEST_F(VsyncManagerRemoteTest, ListenNextVsync, testing::ext::TestSize.Level0)
{
ASSERT_NE(GlobalData::GetInstance()->manager_, nullptr);
sptr<IVsyncCallback> cbnullptr = nullptr;
ASSERT_NE(GlobalData::GetInstance()->manager_->ListenNextVsync(cbnullptr), VSYNC_ERROR_OK);
sptr<IVsyncCallback> cb = new VsyncCallback();
ASSERT_EQ(GlobalData::GetInstance()->manager_->ListenNextVsync(cb), VSYNC_ERROR_OK);
}
} // namespace

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_REMOTE_TEST_H
#define FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_REMOTE_TEST_H
#endif // FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_REMOTE_TEST_H

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_manager_test.h"
#include <gtest/gtest.h>
#include "vsync_callback_stub.h"
#include "vsync_manager.h"
using namespace OHOS;
class VsyncManagerTest : public testing::Test {
public:
void SetUp()
{
manager_ = new VsyncManager();
}
void TearDown()
{
manager_ = nullptr;
}
private:
sptr<VsyncManager> manager_;
MessageParcel data_;
MessageParcel reply_;
MessageOption option_;
};
class VsyncCallback : public VsyncCallbackStub {
public:
void OnVsync(int64_t timestamp)
{
isCall_ = true;
}
bool IsCall() const
{
return isCall_;
}
private:
bool isCall_ = false;
};
namespace {
HWTEST_F(VsyncManagerTest, OnRemoteRequest, testing::ext::TestSize.Level0)
{
ASSERT_NE(manager_->OnRemoteRequest(-1, data_, reply_, option_), 0);
data_.WriteInterfaceToken(IVsyncManager::GetDescriptor());
data_.WriteInt32(0);
ASSERT_EQ(manager_->OnRemoteRequest(IVsyncManager::IVSYNC_MANAGER_LISTEN_NEXT_VSYNC,
data_, reply_, option_), 0);
ASSERT_NE(reply_.ReadInt32(), VSYNC_ERROR_OK);
}
HWTEST_F(VsyncManagerTest, ListenNextVsync, testing::ext::TestSize.Level0)
{
sptr<IVsyncCallback> cb = nullptr;
ASSERT_NE(manager_->ListenNextVsync(cb), VSYNC_ERROR_OK);
cb = new VsyncCallback();
ASSERT_EQ(manager_->ListenNextVsync(cb), VSYNC_ERROR_OK);
}
HWTEST_F(VsyncManagerTest, OnVsync, testing::ext::TestSize.Level0)
{
sptr<VsyncCallback> cb = new VsyncCallback();
sptr<IVsyncCallback> icb = cb;
ASSERT_EQ(manager_->ListenNextVsync(icb), VSYNC_ERROR_OK);
ASSERT_FALSE(cb->IsCall());
constexpr int64_t testTimestamp = 0;
manager_->Callback(testTimestamp);
ASSERT_TRUE(cb->IsCall());
}
} // namespace

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_TEST_H
#define FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_TEST_H
#endif // FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MANAGER_VSYNC_MANAGER_TEST_H

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vsync_module_test.h"
#include <gtest/gtest.h>
#include <system_ability_definition.h>
#include "vsync_module_impl.h"
using namespace OHOS;
class TestVsyncModule : public VsyncModuleImpl {
public:
static TestVsyncModule* GetInstance()
{
static TestVsyncModule m;
return &m;
}
virtual VsyncError InitSA() override
{
return VsyncModuleImpl::InitSA(VSYNC_MANAGER_TEST_ID);
}
private:
TestVsyncModule() = default;
~TestVsyncModule() = default;
};
class VsyncModuleTest : public testing::Test {
public:
static void SetUpTestCase()
{
}
static void TearDownTestCase()
{
}
void SetUp()
{
vm = TestVsyncModule::GetInstance();
}
private:
VsyncModuleImpl* vm;
};
namespace {
HWTEST_F(VsyncModuleTest, Start, testing::ext::TestSize.Level0)
{
ASSERT_EQ(vm->drmFd_, -1);
ASSERT_EQ(vm->vsyncThread_, nullptr);
ASSERT_FALSE(vm->vsyncThreadRunning_);
ASSERT_EQ(vm->Start(), VSYNC_ERROR_OK);
ASSERT_GT(vm->drmFd_, -1);
ASSERT_NE(vm->vsyncThread_, nullptr);
ASSERT_TRUE(vm->vsyncThreadRunning_);
}
HWTEST_F(VsyncModuleTest, Stop, testing::ext::TestSize.Level0)
{
ASSERT_EQ(vm->Stop(), VSYNC_ERROR_OK);
ASSERT_EQ(vm->drmFd_, -1);
ASSERT_EQ(vm->vsyncThread_, nullptr);
ASSERT_FALSE(vm->vsyncThreadRunning_);
ASSERT_NE(vm->Stop(), VSYNC_ERROR_OK);
}
} // namespace

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MODULE_VSYNC_MODULE_TEST_H
#define FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MODULE_VSYNC_MODULE_TEST_H
#endif // FRAMEWORKS_VSYNC_TEST_UNITTEST_VSYNC_MODULE_VSYNC_MODULE_TEST_H

184
frameworks/wm/BUILD.gn Normal file
View File

@ -0,0 +1,184 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
## Build wms_client.so {{{
config("wms_client_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"include/client",
"//utils/system/safwk/native/include",
"//foundation/graphic/standard/frameworks/surface/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("wms_client_public_config") {
include_dirs = [ "//foundation/graphic/standard/interfaces/innerkits/wm" ]
cflags = []
}
ohos_shared_library("wms_client") {
sources = [
"src/client/video_window.cpp",
"src/client/window_manager.cpp",
"src/client/window_manager_controller_client.cpp",
"src/client/window_manager_proxy.cpp",
]
configs = [ ":wms_client_config" ]
public_configs = [
":wms_client_public_config",
"//third_party/libdrm:libdrm_public_config",
]
deps = [
"//foundation/multimedia/media_standard/frameworks/videodisplaymanager:videodisplaymanager",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//third_party/wayland-ivi-extension:libilmClient",
"//third_party/wayland-ivi-extension:libilmCommon",
"//third_party/wayland-ivi-extension:libilmControl",
"//third_party/wayland-ivi-extension:libilmInput",
"//third_party/wayland-protocols_standard:linux_dmabuf_unstable_v1_protocol",
"//third_party/wayland-protocols_standard:viewporter_protocol",
"//third_party/wayland_standard:libwayland_cursor",
"//third_party/wayland_standard:wayland_core_protocol",
"//third_party/weston:ivi_application_protocol",
"//third_party/weston:libweston",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
public_deps = [ "//foundation/graphic/standard:libsurface" ]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build wms_client.so }}}
## Build wms_service {{{
config("wms_service_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"include/server",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
ohos_executable("wms_service") {
install_enable = true
sources = [
"src/server/layer_controller.cpp",
"src/server/window_manager_server.cpp",
"src/server/window_manager_service.cpp",
"src/server/window_manager_stub.cpp",
]
configs = [
":wms_service_config",
":wms_client_public_config",
]
deps = [
"//foundation/graphic/standard:libsurface",
"//foundation/graphic/standard:libvsync_server",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//third_party/libpng:libpng",
"//third_party/wayland-ivi-extension:libilmClient",
"//third_party/wayland-ivi-extension:libilmCommon",
"//third_party/wayland-ivi-extension:libilmControl",
"//third_party/wayland-ivi-extension:libilmInput",
"//third_party/wayland-protocols_standard:linux_dmabuf_unstable_v1_protocol",
"//third_party/wayland_standard:wayland_core_protocol",
"//third_party/weston:libweston",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_L2:samgr_proxy",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build wms_service }}}
## Build wm_test {{{
config("wm_test_config") {
visibility = [ ":*" ]
include_dirs = []
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
ohos_executable("wm_test") {
install_enable = true
sources = [ "src/window_manager_test.cpp" ]
configs = [ ":wm_test_config" ]
deps = [
":wms_client",
"//foundation/graphic/standard:libvsync_client",
"//third_party/zlib:libz",
]
external_deps = [
"ipc:ipc_core",
"hiviewdfx_hilog_native:libhilog",
"samgr_L2:samgr_proxy",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build wm_test }}}
group("test") {
testonly = true
deps = [ "test:test" ]
}

13
frameworks/wm/Readme.md Normal file
View File

@ -0,0 +1,13 @@
The API of windows manager can refer to the file "windows_ manager.h”。
1. First, you need to call windowsmanager:: getinstance() to get the singleton object pointer of WM, and call CreateWindow to create a window (the returned object is an object pointer of window)
2. In addition to the width, height, coordinates and other information of the screen, there are also function pointers for mouse operation in the windowconfig structure passed in when creating a window_ xxxx_cb) and graph refresh callback function sync, which need to be passed in when creating window
3. Through the window pointer, you can perform some operations on the window (such as show, hide, etc.) and get the window ID. through the window ID, you can get the created surface, and then write data to the buffer(Surface::GetInstance(windowid)).

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VIDEO_WINDOW_H
#define VIDEO_WINDOW_H
#include "videodisplaymanager.h"
#include "window_manager.h"
#include "window_manager_controller_client.h"
namespace OHOS {
class VideoWindow : public SubWindow, public RefBase {
public:
VideoWindow(InnerWindowInfo &winInfo);
virtual ~VideoWindow();
static int32_t CreateLayer(InnerWindowInfo &winInfo, uint32_t &layerId, sptr<Surface> &surface);
static void DestroyLayer(uint32_t layerId);
int32_t Init();
sptr<Surface> GetSurface();
int32_t DisplayRectChange(uint32_t layerId, IRect rect);
int32_t ZorderChange(uint32_t layerId, uint32_t zorder);
int32_t TransformChange(uint32_t layerId, TransformType type);
private:
uint32_t layerId_;
sptr<Surface> surface_;
sptr<VideoDisplayManager> display;
sptr<IBufferProducer> producer;
};
} // namespace OHOS
#endif // VIDEO_WINDOW_H

View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_CONTROLLER_CLIENT_H
#define FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_CONTROLLER_CLIENT_H
#include <condition_variable>
#include <iostream>
#include <list>
#include <pthread.h>
#include <securec.h>
#include <string>
#include <vector>
#include <ilm_types.h>
#include <ivi-application-client-protocol.h>
#include <linux-dmabuf-unstable-v1-client-protocol.h>
#include <refbase.h>
#include <surface.h>
#include <touch_event.h>
#include <viewporter-client-protocol.h>
#include <wayland-client-protocol.h>
#include <wayland-cursor.h>
#include "iwindow_manager_service.h"
namespace OHOS {
typedef struct t_wlContextStruct {
struct wl_display* wlDisplay;
struct wl_registry* wlRegistry;
struct wl_compositor* wlCompositor;
struct wl_egl_window* wlNativeWindow;
struct wl_surface* wlSurface;
struct wl_pointer *wl_pointer;
struct wl_keyboard *wlKeyboard;
struct wl_touch *wlTouch;
struct wl_shell_surface* wlShellSurface;
struct ivi_application* iviApp;
struct ivi_surface* iviSurface;
struct zwp_linux_dmabuf_v1 *dmabuf;
struct wl_seat *wl_seat;
struct wl_cursor_theme *cursor_theme;
struct wl_surface *wl_pointer_surface;
struct wl_cursor *cursor;
struct wl_shm *wl_shm;
struct wl_subcompositor *wlSubCompositor;
struct wp_viewporter *viewporter;
uint32_t formats;
uint8_t enable_cursor;
uint8_t button_press;
int32_t width;
int32_t height;
int32_t point_x;
int32_t point_y;
uint32_t mask;
} WLContextStruct;
struct TouchEventInfo {
bool isRefreshed;
int32_t serial;
uint32_t startTime;
uint32_t currentTime;
int32_t x;
int32_t y;
float touchPressure;
};
struct ActionEventInfo {
int32_t touchCount;
bool isDown;
bool isUp;
bool isMotion;
TouchEventInfo touchEventInfos[MAX_TOUCH_NUM];
};
static ActionEventInfo actionEventInfo;
struct InnerWindowInfo {
struct wl_display* wlDisplay;
struct wl_surface* wlSurface;
struct wl_subsurface* wlSubSurface;
struct ivi_surface* iviSurface;
struct wl_buffer* wl_buffer;
struct wp_viewport *viewport;
struct wl_callback *p_cb;
WindowConfig windowconfig;
std::string unitName;
uint32_t windowid;
uint32_t layerid;
uint32_t parentid;
uint32_t voLayerId;
sptr<Surface> surface;
sptr<IBufferConsumerListener> listener;
std::list<uint32_t> childIDList;
bool threadrunning;
bool subwidow;
int32_t width;
int32_t height;
int32_t pos_x;
int32_t pos_y;
void* shm_data;
funcPointerEnter pointerEnterCb;
funcPointerLeave pointerLeaveCb;
funcPointerMotion pointerMotionCb;
funcPointerButton pointerButtonCb;
funcPointerFrame pointerFrameCb;
funcPointerAxis pointerAxisCb;
funcPointerAxisSource pointerAxisSourceCb;
funcPointerAxisStop pointerAxisStopCb;
funcPointerAxisDiscrete pointerAxisDiscreteCb;
funcTouchDown touchDownCb;
funcTouchUp touchUpCb;
funcTouchEmotion touchEmotionCb;
funcTouchFrame touchFrameCb;
funcTouchCancel touchCancelCb;
funcTouchShape touchShapeCb;
funcTouchOrientation touchOrientationCb;
funcOnKey keyboardKeyCb;
funcOnTouch onTouchCb;
funcWindowInfoChange windowInfoChangeCb;
void (* onWindowCreateCb)(uint32_t pid);
bool operator == (const InnerWindowInfo& other) const
{
return windowid == other.windowid;
}
};
class BufferInfo {
public:
BufferInfo();
~BufferInfo();
void AsyncInit();
void Await();
void Async(std::function<void(BufferInfo*)> mutexFunc);
wptr<Surface> surface_;
wptr<SurfaceBuffer> buffer_;
struct wl_buffer* wlBuffer_;
private:
bool created_;
std::mutex createdMutex_;
std::condition_variable createdVariable_;
};
class LayerControllerClient : public RefBase {
public:
static sptr<LayerControllerClient> GetInstance();
InnerWindowInfo* CreateWindow(int32_t id, WindowConfig& config);
InnerWindowInfo* CreateSubWindow(int32_t subid, int32_t parentid, WindowConfig& config);
void CreateWlBuffer(sptr<Surface>& surface, uint32_t id);
void DestroyWindow(int32_t id);
void Move(int32_t id, int32_t x, int32_t y);
void Show(int32_t id);
void Hide(int32_t id);
void ReSize(int32_t id, int32_t width, int32_t height);
void Rotate(int32_t id, int32_t type);
int32_t GetMaxWidth();
int32_t GetMaxHeight();
void ChangeWindowType(int32_t id, WindowType type);
void StartShotScreen(FuncShotDone done_cb);
void StartShotWindow(int32_t winID, FuncShotDone done_cb);
void RegistPointerButtonCb(int id, funcPointerButton cb);
void RegistPointerEnterCb(int id, funcPointerEnter cb);
void RegistPointerLeaveCb(int id, funcPointerLeave cb);
void RegistPointerMotionCb(int id, funcPointerMotion cb);
void RegistPointerAxisDiscreteCb(int id, funcPointerAxisDiscrete cb);
void RegistPointerAxisSourceCb(int id, funcPointerAxisSource cb);
void RegistPointerAxisStopCb(int id, funcPointerAxisStop cb);
void RegistPointerAxisCb(int id, funcPointerAxis cb);
void RegistTouchUpCb(int id, funcTouchUp cb);
void RegistTouchDownCb(int id, funcTouchDown cb);
void RegistTouchEmotionCb(int id, funcTouchEmotion cb);
void RegistTouchFrameCb(int id, funcTouchFrame cb);
void RegistTouchCancelCb(int id, funcTouchCancel cb);
void RegistTouchShapeCb(int id, funcTouchShape cb);
void RegistTouchOrientationCb(int id, funcTouchOrientation cb);
void RegistOnTouchCb(int id, funcOnTouch cb);
void RegistOnKeyCb(int id, funcOnKey cb);
void RegistWindowInfoChangeCb(int id, funcWindowInfoChange cb);
void RegistOnWindowCreateCb(int32_t id, void(* cb)(uint32_t pid));
void SendWindowCreate(uint32_t pid);
static void registry_handle_global(
void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name);
InnerWindowInfo* GetInnerWindowInfoFromId(uint32_t windowid);
void RemoveInnerWindowInfo(uint32_t id);
static void* thread_display_dispatch(void* param);
protected:
bool CreateSurface(int32_t id);
bool initIlm();
bool cleanupIlm();
bool initScreen();
private:
BufferInfo* GetBufferInfo(sptr<SurfaceBuffer>& buffer);
void CleanBufferInfo();
static void BufferRelease(void *data, struct wl_buffer *wlBuffer);
void SetSubSurfaceSize(int32_t id, int32_t width, int32_t height);
static sptr<LayerControllerClient> instance;
LayerControllerClient();
virtual ~LayerControllerClient();
std::mutex mutex;
std::mutex windowListMutex;
std::list<InnerWindowInfo> m_windowList;
std::list<BufferInfo> bufferInfos_;
void wm_register_notification(WindowConfig& config);
uint32_t m_screenId;
int32_t m_screenWidth;
int32_t m_screenHeight;
std::string m_currentUnit;
WLContextStruct wlContextStruct_;
static bool m_bIsThreadRunning;
};
class SurfaceListener : public IBufferConsumerListener {
public:
SurfaceListener(sptr<Surface>& surface, uint32_t windowid);
virtual ~SurfaceListener();
virtual void OnBufferAvailable() override;
private:
wptr<Surface> surface_;
uint32_t windowid_;
};
}
#endif // FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_CONTROLLER_CLIENT_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_PROXY_H
#define FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_PROXY_H
#include "iwindow_manager_service.h"
namespace OHOS {
class WindowManagerProxy : public IRemoteProxy<IWindowManagerService> {
public:
WindowManagerProxy(const sptr<IRemoteObject> &impl);
~WindowManagerProxy();
virtual int32_t CreateWindow(WindowConfig& config) override;
virtual void SwitchTop(int windowID) override;
virtual void DestroyWindow(int windowID) override;
private:
static inline BrokerDelegator<WindowManagerProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_WM_INCLUDE_CLIENT_WINDOW_MANAGER_PROXY_H

Some files were not shown because too many files have changed in this diff Show More