Surface và SurfaceHolder

Đối tượng bề mặt cho phép ứng dụng kết xuất hình ảnh để hiển thị 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 (mặt) là giao diện để nhà sản xuất trao đổi vùng đệm với người dùng.

BufferQueue cho một nền tảng hiển thị thường được định cấu hình để lưu vào vùng đệm ba lần. Bộ đệm được phân bổ theo yêu cầu, vì vậy, nếu trình tạo tạo bộ đệ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ó hai bộ đệ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 sử dụng bộ nhớ. Bạn có thể thấy thông tin tóm tắt về các vùng đệm liên kết với mọi lớp trong đầu ra dumpsys SurfaceFlinger.

Hầu hết ứ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 sẽ kết xuất lên các nền tảng bằng cách sử dụng canvas.

Kết xuất Canvas

Thư viện đồ hoạ Skia cung cấp tính năng triển khai canvas. Nếu muốn vẽ một hình chữ nhật, bạn hãy gọi Canvas API. API này sẽ đặt các byte trong vùng đệm một cách thích hợp. Để đảm bảo rằng hai ứng dụng không cập nhật một vùng đệm cùng một lúc hoặc ghi vào vùng đệm trong khi 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 để xử lý 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() 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 vùng đệm từ BufferQueue, vùng đệ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 vùng đệm, nội dung trước đó vẫn còn. Nếu bạn liên tục gọi lockCanvas()unlockCanvasAndPost() mà không vẽ gì, thì trình tạo sẽ luân phiên giữa các khung hình đã kết xuất trước đó.

Mã khoá/mở khoá bề mặt giữ lại tệp đối chiếu đến vùng đệm đã kết xuất trước đó. Nếu bạn chỉ định một vùng bẩn khi khoá bề mặt, thì vùng này sẽ sao chép các pixel không bẩn từ vùng đệm trước đó. SurfaceFlinger hoặc HWC thường xử lý bộ đệm; nhưng vì chúng ta chỉ cần đọc từ bộ đệ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 sử 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 làm việc với các nền tảng muốn có SurfaceHolder, vì các API để lấy và đặt tham số nền tảng được triển khai thông qua SurfaceHolder. SurfaceView chứa một SurfaceHolder.

Hầu hết các thành phần tương tác với thành phần 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 nền tảng.