Lớp và màn hình là hai thành phần gốc đại diện cho công việc kết hợp và tương tác với phần cứng hiển thị.
Lớp
Lớp (layer) là thành phần kết hợp quan trọng nhất. Lớp là một tổ hợp của nền tảng và một thực thể của SurfaceControl
. Mỗi lớp có một tập hợp các thuộc tính xác định cách lớp đó tương tác với các lớp khác. Các thuộc tính của lớp được mô tả trong bảng dưới đây.
Thuộc tính | Mô tả |
---|---|
Vị trí | Xác định vị trí lớp xuất hiện trên màn hình. Bao gồm thông tin như vị trí các cạnh của một lớp và thứ tự Z của lớp đó so với các lớp khác (cho dù lớp đó ở trước hay phía sau các lớp khác). |
Nội dung | Xác định cách hiển thị nội dung trên lớp trong giới hạn do các thuộc tính vị trí xác định. Bao gồm các thông tin như cắt (để mở rộng một phần nội dung nhằm lấp đầy ranh giới của lớp) và biến đổi (để hiển thị nội dung đã xoay hoặc lật). |
Bản sáng tác | Xác định cách kết hợp lớp này với các lớp khác. Bao gồm những thông tin như chế độ phối và giá trị alpha trên toàn lớp cho quá trình kết hợp alpha. |
Tối ưu hoá | Cung cấp thông tin không thực sự cần thiết để kết hợp chính xác lớp, nhưng thiết bị Trình tổng hợp phần cứng (HWC) có thể sử dụng thông tin đó để tối ưu hoá cách thực hiện quá trình kết hợp. Bao gồm những thông tin như khu vực hiển thị của lớp và phần nào của lớp đã được cập nhật kể từ khung trước. |
Màn hình
Màn hình là một thành phần kết hợp quan trọng khác. Một hệ thống có thể có nhiều màn hình và màn hình có thể được thêm vào hoặc bị xoá trong quá trình hoạt động bình thường của hệ thống. Màn hình được thêm/xoá theo yêu cầu của HWC hoặc theo yêu cầu của khung. Các yêu cầu hiển thị của thiết bị HWC được thêm vào hoặc bị xoá khi màn hình ngoài được kết nối hoặc ngắt kết nối khỏi thiết bị, gọi là hot Cắm. Ứng dụng yêu cầu màn hình ảo, nội dung của màn hình này được kết xuất vào vùng đệm ngoài màn hình thay vì màn hình thực.
Màn hình ảo
SurfaceFlinger hỗ trợ màn hình trong (được tích hợp vào điện thoại hoặc máy tính bảng), màn hình ngoài (chẳng hạn như TV được kết nối qua HDMI) và một hoặc nhiều màn hình ảo cung cấp đầu ra tổng hợp trong hệ thống. Bạn có thể dùng màn hình ảo để ghi lại màn hình hoặc gửi màn hình qua mạng. Các khung hình được tạo cho màn hình ảo được ghi vào BufferQueue.
Màn hình ảo có thể dùng chung một nhóm lớp với màn hình chính (ngăn xếp lớp) hoặc có nhóm lớp riêng. Không có VSYNC cho màn hình ảo, vì vậy, VSYNC cho màn hình nội bộ sẽ kích hoạt thành phần cho tất cả màn hình.
Trên các phương thức triển khai HWC hỗ trợ các màn hình này, màn hình ảo có thể được kết hợp với OpenGL ES (GLES), HWC hoặc cả GLES và HWC. Trên các phương thức triển khai không hỗ trợ, màn hình ảo luôn được kết hợp bằng GLES.
Nghiên cứu điển hình: screenrecord
Lệnh screenrecord
cho phép người dùng ghi lại mọi thứ xuất hiện trên màn hình dưới dạng tệp .mp4
trên ổ đĩa. Để triển khai tính năng này, hệ thống sẽ nhận các khung hình tổng hợp từ SurfaceFlinger, ghi các khung hình đó vào bộ mã hoá video, sau đó ghi dữ liệu video đã mã hoá vào một tệp. Bộ mã hoá và giải mã video được quản lý bằng một quy trình riêng (mediaserver
), vì vậy, các vùng đệm đồ hoạ lớn phải di chuyển xung quanh hệ thống. Để thách thức hơn, mục tiêu là quay video 60 khung hình/giây ở độ phân giải đầy đủ. Chìa khoá để thực hiện việc này một cách hiệu quả là BufferQueue.
Lớp MediaCodec
cho phép ứng dụng cung cấp dữ liệu dưới dạng byte thô trong vùng đệm hoặc thông qua một nền tảng. Khi screenrecord
yêu cầu quyền truy cập vào bộ mã hoá video, quy trình mediaserver
sẽ tạo một BufferQueue, tự kết nối với phía người dùng, sau đó chuyển phía nhà sản xuất trở lại screenrecord
dưới dạng nền tảng.
Sau đó, tiện ích screenrecord
yêu cầu SurfaceFlinger tạo một màn hình ảo phản chiếu màn hình chính (tức là có tất cả các lớp giống nhau) và hướng dẫn màn hình ảo này gửi đầu ra đến bề mặt đến từ quy trình mediaserver
. Trong trường hợp này, SurfaceFlinger là tác nhân tạo ra vùng đệm chứ không phải là đối tượng tiêu thụ.
Sau khi định cấu hình hoàn tất, screenrecord
sẽ kích hoạt khi dữ liệu được mã hoá xuất hiện. Khi các ứng dụng vẽ, bộ đệm của chúng sẽ chuyển đến SurfaceFlinger,
và SurfaceFlinger sẽ kết hợp các bộ đệm đó thành một bộ đệm duy nhất được gửi trực tiếp đến bộ mã hoá video trong quy trình mediaserver
. Quy trình screenrecord
tuyệt đối không nhìn thấy toàn bộ khung hình. Trong nội bộ, quá trình mediaserver
có cách riêng để di chuyển vùng đệm xung quanh, đồng thời truyền dữ liệu theo tay cầm, giảm thiểu hao tổn.
Nghiên cứu điển hình: mô phỏng màn hình phụ
WindowManager có thể yêu cầu SurfaceFlinger tạo một lớp hiển thị mà SurfaceFlinger đóng vai trò là người dùng BufferQueue. Bạn cũng có thể yêu cầu SurfaceFlinger tạo một màn hình ảo, trong đó SurfaceFlinger đóng vai trò là nhà sản xuất BufferQueue.
Nếu bạn kết nối màn hình ảo với một lớp hiển thị, một vòng lặp kín sẽ được tạo trong đó màn hình tổng hợp xuất hiện trong một cửa sổ. Cửa sổ đó hiện là một phần của đầu ra tổng hợp, vì vậy, vào lần làm mới tiếp theo, hình ảnh tổng hợp bên trong cửa sổ cũng sẽ hiển thị nội dung của cửa sổ. Để xem cách hoạt động của tính năng này, hãy bật Tuỳ chọn cho nhà phát triển trong phần Cài đặt, chọn Mô phỏng màn hình phụ rồi bật một cửa sổ. Để xem màn hình phụ hoạt động, hãy sử dụng screenrecord
để ghi lại thao tác bật màn hình, sau đó phát lại từng khung hình.