Lớp và màn hình là hai nguyên hàm thể hiện công việc tổng hợp và tương tác với phần cứng màn hình.
Lớp
Lớp là đơn vị cấu thành quan trọng nhất. Một lớp là sự kết hợp giữa một bề mặt và một thể hiện 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 nó tương tác với các lớp khác. Thuộc tính lớp được mô tả trong bảng dưới đây.
Tài sản | Sự miêu tả |
---|---|
Vị trí | Xác định nơi lớp xuất hiện trên màn hình của nó. 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 nó so với các lớp khác (cho dù nó nên ở phía trước hay phía sau các lớp khác). |
Nội dung | Xác định cách trình bày nội dung hiển thị trên lớp trong giới hạn được xác định bởi các thuộc tính vị trí. Bao gồm các thông tin như cắt xén (để mở rộng một phần nội dung để lấp đầy giới hạn của lớp) và biến đổi (để hiển thị nội dung được xoay hoặc lật). |
Thành phần | Xác định cách lớp này sẽ được kết hợp với các lớp khác. Bao gồm thông tin như chế độ hòa trộn và giá trị alpha trên toàn lớp để tổng hợp alpha . |
Tối ưu hóa | Cung cấp thông tin không thực sự cần thiết để kết hợp lớp một cách chính xác, nhưng thông tin đó có thể được thiết bị Trình soạn thảo phần cứng (HWC) sử dụng để tối ưu hóa cách thức thực hiện thành phần. Bao gồm thông tin như vùng 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 đó. |
Hiển thị
Màn hình là một đơn vị cấu thành 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 hoặc xóa trong quá trình hoạt động bình thường của hệ thống. Hiển thị được thêm/xóa 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 hoặc xóa 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ị, được gọi là cắm nóng . Khách hàng yêu cầu màn hình ảo , nội dung của nó được hiển thị vào bộ đệm ngoài màn hình thay vì hiển thị vật lý.
Màn hình ảo
SurfaceFlinger hỗ trợ màn hình bên trong (được tích hợp trong điện thoại hoặc máy tính bảng), màn hình bên 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. Màn hình ảo có thể được sử dụng để ghi lại màn hình hoặc gửi màn hình qua mạng. Các khung được tạo cho màn hình ảo được ghi vào BufferQueue.
Màn hình ảo có thể chia sẻ cùng một bộ lớp với màn hình chính (ngăn xếp lớp) hoặc có bộ riêng. Không có VSYNC cho màn hình ảo, do đó VSYNC cho màn hình bên trong sẽ kích hoạt thành phần cho tất cả các màn hình.
Khi triển khai HWC hỗ trợ chúng, màn hình ảo có thể được kết hợp với OpenGL ES (GLES), HWC hoặc cả GLES và HWC. Khi triển khai không hỗ trợ, màn hình ảo luôn được tổng hợp bằng GLES.
Nghiên cứu điển hình: bản ghi màn hình
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. Để thực hiện điều này, hệ thống nhận các khung hình tổng hợp từ SurfaceFlinger, ghi chúng vào bộ mã hóa video, sau đó ghi dữ liệu video được mã hóa vào một tệp. Các codec video được quản lý bởi một quy trình riêng biệt ( mediaserver
), do đó bộ đệm đồ họa lớn phải di chuyển xung quanh hệ thống. Để làm cho nó trở nên khó khăn hơn, mục tiêu là quay video 60 khung hình / giây ở độ phân giải đầy đủ. Chìa khóa để thực hiện công việc này 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 bộ đệm hoặc thông qua một bề mặt. Khi screenrecord
yêu cầu quyền truy cập vào bộ mã hóa video, quy trình mediaserver
sẽ tạo một BufferQueue, tự kết nối với phía người tiêu dùng, sau đó chuyển phía nhà sản xuất trở lại screenrecord
dưới dạng bề mặt.
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 (nghĩa là nó có tất cả các lớp giống nhau) và hướng dẫn nó gửi đầu ra tới bề mặt xuất phát từ quy trình mediaserver
. Trong trường hợp này, SurfaceFlinger là nhà sản xuất bộ đệm hơn là người tiêu dùng.
Sau khi cấu hình hoàn tất, screenrecord
sẽ kích hoạt khi dữ liệu được mã hóa xuất hiện. Khi các ứng dụng vẽ, bộ đệm của chúng sẽ di chuyển đến SurfaceFlinger, nơi kết hợp chúng thành một bộ đệm duy nhất được gửi trực tiếp đến bộ mã hóa video trong quy trình mediaserver
. Quá trình screenrecord
không bao giờ nhìn thấy toàn bộ khung hình. Trong nội bộ, quy trình mediaserver
có cách di chuyển bộ đệm xung quanh riêng và cũng truyền dữ liệu bằng tay cầm, giảm thiểu chi phí.
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 tiêu dùng BufferQueue. 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 lớp hiển thị, một vòng lặp khép kín sẽ được tạo trong đó màn hình tổng hợp xuất hiện trong cửa sổ. Cửa sổ đó bây giờ là một phần của đầu ra tổng hợp, vì vậy trong lần làm mới tiếp theo, hình ảnh tổng hợp bên trong cửa sổ cũng hiển thị nội dung cửa sổ. Để thấy tính năng này hoạt động, hãy bật Tùy chọn nhà phát triển trong Cài đặt , chọn Mô phỏng màn hình phụ và bật một cửa sổ. Để xem hoạt động của màn hình phụ, hãy sử dụng screenrecord
để ghi lại hành động bật màn hình rồi phát lại từng khung hình.