Các đối tượng bề mặt cho phép ứng dụng hiển thị hình ảnh được hiển thị trên màn hình. Giao diện SurfaceHolder cho phép ứng dụng chỉnh sửa và kiểm soát các bề mặt.
Bề mặt
Bề mặt là một giao diện để nhà sản xuất trao đổi bộ đệm với người tiêu dùng.
BufferQueue cho bề mặt hiển thị thường được cấu hình để đệm ba lần. Bộ đệm được phân bổ theo yêu cầu, vì vậy nếu nhà sản xuất 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. Phân bổ bộ đệm theo yêu cầu giúp giảm thiểu mức tiêu thụ bộ nhớ. Bạn có thể xem bản tóm tắt về bộ đệm được liên kết với mọi lớp trong đầu ra dumpsys SurfaceFlinger
.
Hầu hết các máy khách hiển thị trên các bề mặt bằng OpenGL ES hoặc Vulkan . Tuy nhiên, một số máy khách hiển thị trên các bề mặt bằng canvas.
Kết xuất canvas
Việc triển khai canvas được cung cấp bởi Thư viện đồ họa Skia . Nếu bạn muốn vẽ một hình chữ nhật, bạn gọi API Canvas để đặt byte vào bộ đệm một cách thích hợp. Để đảm bảo rằng bộ đệm không được hai máy khách cập nhật cùng một lúc hoặc được ghi vào trong khi đang hiển thị, hãy khóa bộ đệm để truy cập vào bộ đệm đó. Sử dụng các lệnh sau để làm việc với khóa canvas:
-
lockCanvas()
khóa bộ đệm để hiển thị trên CPU và trả về Canvas để sử dụng cho việc vẽ. -
unlockCanvasAndPost()
mở khóa bộ đệm và gửi nó tới bộ tổng hợp. -
lockHardwareCanvas()
khóa bộ đệm để hiển thị trên GPU và trả về canvas để sử dụng cho việc vẽ.
Lần đầu tiên nhà sản xuất yêu cầu bộ đệm từ BufferQueue, bộ đệm sẽ được phân bổ và khởi tạo về 0. Việc khởi tạo là cần thiết để tránh việc vô tình chia sẻ dữ liệu giữa các tiến trình. Tuy nhiên, nếu bạn sử dụng lại bộ đệm thì nội dung trước đó vẫn còn. Nếu bạn liên tục gọi lockCanvas()
và unlockCanvasAndPost()
mà không vẽ bất cứ thứ gì, nhà sản xuất sẽ chuyển đổi giữa các khung được hiển thị trước đó.
Mã khóa/mở khóa bề mặt giữ tham chiếu đến bộ đệm được hiển thị trước đó. Nếu bạn chỉ định một vùng bẩn khi khóa bề mặt, nó 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 đợi quyền truy cập độc quyền.
SurfaceHolder
SurfaceHolder là 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ố máy khách làm việc với các bề mặt muốn có SurfaceHolder, vì các API để lấy và đặt các tham số bề mặt được triển khai thông qua SurfaceHolder. SurfaceView chứa SurfaceHolder.
Hầu hết các thành phần tương tác với một khung nhìn đều liên quan đến SurfaceHolder. Một số API khác, chẳng hạn như MediaCodec, hoạt động trên bề mặt.