Lớp và màn hình là 2 thành phần cơ bản đại diện cho hoạt động kết hợp và tương tác với phần cứng màn hình.
Lớp
Lớp là đơn vị quan trọng nhất của thành phần. Lớp là sự kết hợp giữa một 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 Layer được mô tả trong bảng sau:
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ủa 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 (liệu lớp đó có nằm trước hay sau các lớp khác). |
Nội dung | Xác định cách nội dung hiển thị trên lớp sẽ xuất hiện trong phạm vi được xác định bằng các thuộc tính vị trí. 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 thông tin như chế độ hoà trộn và giá trị alpha trên toàn lớp cho thành phần 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 có thể được thiết bị Hardware Composer (HWC) dùng để tối ưu hoá cách thiết bị thực hiện việc kết hợp. Bao gồm các 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 hình trước. |
Màn hình
Hiển thị là một đơn vị 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 hoặc xoá trong quá trình hoạt động bình thường của hệ thống. Các màn hình được thêm hoặc xoá theo yêu cầu của HWC hoặc theo yêu cầu của khung. Thiết bị HWC yêu cầu thêm hoặc xoá màn hình khi một màn hình ngoài được kết nối hoặc ngắt kết nối với thiết bị. Quá trình này được gọi là cắm nóng. Các ứ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 một vùng đệm ngoài màn hình thay vì vào một 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 kết nối qua HDMI) và một hoặc nhiều màn hình ảo giúp đầu ra kết hợp có sẵn 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 sẽ được ghi vào BufferQueue.
Màn hình ảo có thể dùng chung cùng 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 trong sẽ kích hoạt thành phần cho tất cả màn hình.
Trên những chế độ triển khai HWC hỗ trợ các chế độ này, bạn có thể kết hợp các màn hình ảo với OpenGL ES (GLES), HWC hoặc cả GLES và HWC. Trên các chế độ 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 việc này, hệ thống sẽ nhận các khung hình kết hợp từ SurfaceFlinger, ghi các khung hình đó vào bộ mã hoá video, rồi ghi dữ liệu video đã mã hoá vào một tệp. Các bộ mã hoá và giải mã video được quản lý bằng một quy trình riêng biệt (mediaserver
), vì vậy, các vùng đệm đồ hoạ lớn phải di chuyển xung quanh hệ thống. Để tăng độ khó, mục tiêu là quay video 60 khung hình/giây ở độ phân giải tối đa. Chìa khoá để hoạt động này diễn ra 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 các vùng đệm hoặc thông qua một vùng hiển thị. Khi screenrecord
yêu cầu quyền truy cập vào một bộ mã hoá video, quy trình mediaserver
sẽ tạo một BufferQueue, kết nối chính nó 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 một nền tảng.
Tiện ích screenrecord
sau đó 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 đó gửi đầu ra đến 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 các vùng đệm chứ không phải người dùng.
Sau khi quá trình đị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ẽ, các vùng đệm của chúng sẽ chuyển đến SurfaceFlinger, vùng đệm này sẽ kết hợp các vùng đệm đó thành một vùng đệ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
không bao giờ nhìn thấy toàn bộ khung hình. Về nội bộ, quy trình mediaserver
có cách riêng để di chuyển các vùng đệm xung quanh, đồng thời truyền dữ liệu theo mã nhận dạng, giúp 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 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ột màn hình ảo với một lớp hiển thị, một vòng khép kín sẽ được tạo ra, trong đó màn hình được kết hợp sẽ xuất hiện trong một cửa sổ. Giờ đây, cửa sổ đó là một phần của đầu ra kết hợp, vì vậy, trong lần làm mới tiếp theo, hình ảnh kết hợp bên trong cửa sổ cũng sẽ cho thấy nội dung của cửa sổ. Để xem tính năng này hoạt động, 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 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.