Surface và SurfaceHolder

Các đối tượng Surface cho phép ứng dụng kết xuất hình ảnh sẽ xuất hiện trên màn hình. Giao diện SurfaceHolder cho phép các ứng dụng chỉnh sửa và kiểm soát các nền tảng.

Bề mặt

Surface là một giao diện để nhà sản xuất trao đổi các vùng đệm với người tiêu dùng.

Các nền tảng hiển thị thường dùng BufferQueue được định cấu hình cho bộ nhớ đệm gấp ba. Các vùng đệm được phân bổ theo yêu cầu, vì vậy, nếu nhà sản xuất tạo vùng đệm đủ chậm, chẳng hạn như ở tốc độ 30 khung hình/giây trên màn hình 60 khung hình/giây, thì có thể chỉ có 2 vùng đệm được phân bổ trong hàng đợi. Việc phân bổ vùng đệm theo yêu cầu giúp giảm thiểu mức tiêu thụ bộ nhớ. Bạn có thể xem thông tin tóm tắt về các vùng đệm được liên kết với mọi lớp trong đầu ra dumpsys SurfaceFlinger.

Hầu hết các ứng dụng đều kết xuất lên các nền tảng bằng OpenGL ES hoặc Vulkan. Tuy nhiên, một số ứng dụng hiển thị lên các nền tảng bằng canvas.

Kết xuất canvas

Thư viện đồ hoạ Skia cung cấp phương thức triển khai canvas. Nếu muốn vẽ một hình chữ nhật, bạn sẽ gọi Canvas API. API này sẽ đặt các byte trong một vùng đệm một cách thích hợp. Để đảm bảo rằng hai ứng dụng không cùng lúc cập nhật một vùng đệm hoặc ghi vào vùng đệm trong khi vùng đệm đang hiển thị, hãy khoá vùng đệm để truy cập vào vùng đệm đó. Sử dụng các lệnh sau để thao tác với khoá canvas:

  • lockCanvas() khoá vùng đệm để kết xuất trên CPU và trả về một Canvas để dùng cho việc vẽ.
  • unlockCanvasAndPost() sẽ mở khoá vùng đệm và gửi vùng đệm đó đến trình kết hợp.
  • lockHardwareCanvas() khoá vùng đệm để kết xuất trên GPU và trả về một canvas để dùng cho việc vẽ.

Lần đầu tiên nhà sản xuất yêu cầu một bộ đệm từ BufferQueue, bộ đệm sẽ được phân bổ và khởi tạo thành 0. Bạn cần khởi chạy để tránh vô tình chia sẻ dữ liệu giữa các quy trình. Tuy nhiên, nếu bạn sử dụng lại một vùng đệm, nội dung trước đó vẫn sẽ xuất hiện. Nếu bạn gọi lockCanvas()unlockCanvasAndPost() nhiều lần mà không vẽ gì, thì nhà sản xuất sẽ chuyển đổi giữa các khung hình đã kết xuất trước đó.

Mã khoá/mở khoá bề mặt giữ một tham chiếu đến vùng đệm đã kết xuất trước đó. Nếu bạn chỉ định một vùng bị bẩn khi khoá vùng hiển thị, thì vùng này sẽ sao chép các pixel không bị bẩn từ vùng đệm trước đó. SurfaceFlinger hoặc HWC thường xử lý vùng đệm; nhưng vì bạn chỉ cần đọc từ vùng đệm nên không cần phải chờ quyền truy cập độc quyền.

SurfaceHolder

SurfaceHolder là một giao diện mà hệ thống dùng để chia sẻ quyền sở hữu các bề mặt với ứng dụng. Một số ứng dụng hoạt động với các nền tảng muốn có một SurfaceHolder, vì các API để nhận và đặt tham số nền tảng được triển khai thông qua một SurfaceHolder. SurfaceView chứa một SurfaceHolder.

Hầu hết các thành phần tương tác với một khung hiển thị đều liên quan đến SurfaceHolder. Một số API khác, chẳng hạn như MediaCodec, hoạt động trên chính bề mặt.