namespace viz {
+OffscreenTBMBuffer::OffscreenTBMBuffer() {}
+
+OffscreenTBMBuffer::~OffscreenTBMBuffer() {
+ Destroy();
+}
+
+void OffscreenTBMBuffer::Create(int width, int height) {
+ tbm_surface_ = tbm_surface_create(width, height, TBM_FORMAT_ARGB8888);
+
+ if (gpu::EGLImageTizen::IsSupported()) {
+ egl_image_ = gpu::EGLImageTizen::MakeScopedEGLImage(tbm_surface_);
+ } else if (gpu::EGLImageDMABUF::IsSupported()) {
+ egl_image_ = gpu::EGLImageDMABUF::MakeScopedEGLImage(tbm_surface_);
+ } else {
+ LOG(ERROR) << "no fallback extension for OffscreenTBMBuffer::Create";
+ assert(false);
+ }
+
+ glGenTextures(1, &texture_id_);
+ glBindTexture(GL_TEXTURE_2D, texture_id_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_.get());
+}
+
+void OffscreenTBMBuffer::Destroy() {
+ if (egl_image_.get()) {
+ egl_image_.reset();
+ }
+
+ if (tbm_surface_) {
+ if (tbm_surface_destroy(tbm_surface_) != TBM_SURFACE_ERROR_NONE) {
+ LOG(ERROR) << "Failed to destroy tbm surface.";
+ }
+ tbm_surface_ = 0;
+ }
+}
+
SkiaOutputDeviceOffscreenTBM::SkiaOutputDeviceOffscreenTBM(
scoped_refptr<gpu::SharedContextState> context_state,
gfx::SurfaceOrigin origin,
has_alpha,
memory_tracker,
did_swap_buffer_complete_callback) {
- max_buffer_size_ = 1;
+ max_buffer_size_ = MAX_OFFSCREEN_BUFFER_SIZE;
}
SkiaOutputDeviceOffscreenTBM::~SkiaOutputDeviceOffscreenTBM() {
}
void SkiaOutputDeviceOffscreenTBM::EnsureBackbuffer() {
- if (size_.IsEmpty())
+ if (size_.IsEmpty()) {
return;
-
- tbm_surface_ = tbm_surface_create(
- size_.width(), size_.height(), TBM_FORMAT_ARGB8888);
-
- if (gpu::EGLImageTizen::IsSupported()) {
- egl_image_ = gpu::EGLImageTizen::MakeScopedEGLImage(tbm_surface_);
- } else if (gpu::EGLImageDMABUF::IsSupported()) {
- egl_image_ = gpu::EGLImageDMABUF::MakeScopedEGLImage(tbm_surface_);
- } else {
- LOG(ERROR) << "no fallback extension for SkiaOutputDeviceOffscreenTBM::EnsureBackbuffer";
- assert(false);
}
- GLuint texture_id = 0;
- glGenTextures(1, &texture_id);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_.get());
-
- gpu::GetGrBackendTexture(context_state_->feature_info(), GL_TEXTURE_2D, size_,
- texture_id, GR_GL_RGBA8,
- context_state_->gr_context()->threadSafeProxy(),
- &(backend_textures_[0]));
+ for (int i = 0; i < max_buffer_size_; i++) {
+ tbm_buffers_[i].Create(size_.width(), size_.height());
+ gpu::GetGrBackendTexture(context_state_->feature_info(), GL_TEXTURE_2D,
+ size_, tbm_buffers_[i].texture_id(), GR_GL_RGBA8,
+ context_state_->gr_context()->threadSafeProxy(),
+ &(backend_textures_[i]));
+ }
}
void SkiaOutputDeviceOffscreenTBM::DiscardBackbuffer() {
- if (tbm_surface_) {
- if (tbm_surface_destroy(tbm_surface_) != TBM_SURFACE_ERROR_NONE)
- LOG(ERROR) << "Failed to destroy tbm surface.";
- tbm_surface_ = 0;
+ for (int i = 0; i < max_buffer_size_; i++) {
+ tbm_buffers_[i].Destroy();
}
-
SkiaOutputDeviceOffscreen::DiscardBackbuffer();
}
size_t SkiaOutputDeviceOffscreenTBM::GetTextureID() {
- return reinterpret_cast<size_t>(tbm_surface_);
+ return reinterpret_cast<size_t>(
+ tbm_buffers_[last_swapped_buffer_index_].tbm_surface());
}
bool SkiaOutputDeviceOffscreenTBM::NeedSync() {
- return false;
+ return SkiaOutputDeviceOffscreen::NeedSync();
+}
+
+bool SkiaOutputDeviceOffscreenTBM::ForceSync() {
+ return true;
}
} // namespace viz
namespace viz {
+class OffscreenTBMBuffer {
+ public:
+ OffscreenTBMBuffer();
+ ~OffscreenTBMBuffer();
+
+ void Create(int width, int height);
+ void Destroy();
+
+ GLuint texture_id() { return texture_id_; }
+ void* tbm_surface() { return tbm_surface_; }
+
+ private:
+ tbm_surface_h tbm_surface_ = 0;
+ gl::ScopedEGLImage egl_image_;
+ GLuint texture_id_ = 0;
+};
+
class SkiaOutputDeviceOffscreenTBM : public SkiaOutputDeviceOffscreen {
public:
SkiaOutputDeviceOffscreenTBM(
~SkiaOutputDeviceOffscreenTBM() override;
+ bool ForceSync() override;
+
void EnsureBackbuffer() override;
void DiscardBackbuffer() override;
bool NeedSync() override;
private:
- tbm_surface_h tbm_surface_ = 0;
- gl::ScopedEGLImage egl_image_;
+ OffscreenTBMBuffer tbm_buffers_[MAX_OFFSCREEN_BUFFER_SIZE];
};
} // namespace viz