15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/common/content_export.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox_holder.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Rect; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Size; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace gpu { 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ContextSupport; 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct Mailbox; 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace media { 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class VideoFrame; 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SkRegion; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class GLHelperScaling; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedGLuint { 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GLuint* ids); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedGLuint(gpu::gles2::GLES2Interface* gl, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GenFunc gen_func, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFunc delete_func) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : gl_(gl), id_(0u), delete_func_(delete_func) { 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (gl_->*gen_func)(1, &id_); 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) operator GLuint() const { return id_; } 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint id() const { return id_; } 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ~ScopedGLuint() { 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (id_ != 0) { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (gl_->*delete_func_)(1, &id_); 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu::gles2::GLES2Interface* gl_; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint id_; 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DeleteFunc delete_func_; 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedGLuint); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedBuffer : public ScopedGLuint { 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedGLuint(gl, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::GenBuffers, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::DeleteBuffers) {} 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedFramebuffer : public ScopedGLuint { 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedGLuint(gl, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::GenFramebuffers, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::DeleteFramebuffers) {} 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedTexture : public ScopedGLuint { 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ScopedTexture(gpu::gles2::GLES2Interface* gl) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedGLuint(gl, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::GenTextures, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::DeleteTextures) {} 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target> 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class ScopedBinder { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint id); 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : gl_(gl), bind_func_(bind_func) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (gl_->*bind_func_)(Target, id); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); } 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu::gles2::GLES2Interface* gl_; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BindFunc bind_func_; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedBinder); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target> 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedBufferBinder : ScopedBinder<Target> { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {} 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target> 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedFramebufferBinder : ScopedBinder<Target> { 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedBinder<Target>(gl, 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) id, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &gpu::gles2::GLES2Interface::BindFramebuffer) {} 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target> 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedTextureBinder : ScopedBinder<Target> { 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ReadbackYUVInterface; 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GLHelperReadbackSupport; 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Provides higher level operations on top of the gpu::gles2::GLES2Interface 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interfaces. 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class CONTENT_EXPORT GLHelper { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLHelper(gpu::gles2::GLES2Interface* gl, 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gpu::ContextSupport* context_support); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~GLHelper(); 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) enum ScalerQuality { 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bilinear single pass, fastest possible. 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SCALER_QUALITY_FAST = 1, 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bilinear upscale + N * 50% bilinear downscales. 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This is still fast enough for most purposes and 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Image quality is nearly as good as the BEST option. 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SCALER_QUALITY_GOOD = 2, 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bicubic upscale + N * 50% bicubic downscales. 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Produces very good quality scaled images, but it's 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 2-8x slower than the "GOOD" quality, so it's not always 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // worth it. 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SCALER_QUALITY_BEST = 3, 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) }; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copies the block of pixels specified with |src_subrect| from |src_texture|, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scales it to |dst_size|, and writes it into |out|. 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |src_size| is the size of |src_texture|. The result is in |out_color_type| 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // format and is potentially flipped vertically to make it a correct image 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representation. |callback| is invoked with the copy result when the copy 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation has completed. 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that the src_texture will have the min/mag filter set to GL_LINEAR 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and wrap_s/t set to CLAMP_TO_EDGE in this call. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CropScaleReadbackAndCleanTexture( 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint src_texture, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& src_size, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& src_subrect, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& dst_size, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* out, 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const SkColorType out_color_type, 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::Callback<void(bool)>& callback, 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GLHelper::ScalerQuality quality); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Copies the block of pixels specified with |src_subrect| from |src_mailbox|, 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // scales it to |dst_size|, and writes it into |out|. 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |src_size| is the size of |src_mailbox|. The result is in |out_color_type| 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // format and is potentially flipped vertically to make it a correct image 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // representation. |callback| is invoked with the copy result when the copy 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // operation has completed. 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Note that the texture bound to src_mailbox will have the min/mag filter set 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to GL_LINEAR and wrap_s/t set to CLAMP_TO_EDGE in this call. src_mailbox is 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // assumed to be GL_TEXTURE_2D. 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void CropScaleReadbackAndCleanMailbox( 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gpu::Mailbox& src_mailbox, 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint32 sync_point, 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Size& src_size, 1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Rect& src_subrect, 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Size& dst_size, 1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned char* out, 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const SkColorType out_color_type, 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::Callback<void(bool)>& callback, 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GLHelper::ScalerQuality quality); 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copies the texture data out of |texture| into |out|. |size| is the 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size of the texture. No post processing is applied to the pixels. The 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // texture is assumed to have a format of GL_RGBA with a pixel type of 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // GL_UNSIGNED_BYTE. This is a blocking call that calls glReadPixels on the 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // current OpenGL context. 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ReadbackTextureSync(GLuint texture, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& src_rect, 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unsigned char* out, 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkColorType format); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ReadbackTextureAsync(GLuint texture, 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Size& dst_size, 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unsigned char* out, 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkColorType color_type, 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Callback<void(bool)>& callback); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a copy of the specified texture. |size| is the size of the texture. 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that the src_texture will have the min/mag filter set to GL_LINEAR 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and wrap_s/t set to CLAMP_TO_EDGE in this call. 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint CopyTexture(GLuint texture, const gfx::Size& size); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a scaled copy of the specified texture. |src_size| is the size of 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the texture and |dst_size| is the size of the resulting copy. 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that the src_texture will have the min/mag filter set to GL_LINEAR 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and wrap_s/t set to CLAMP_TO_EDGE in this call. 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint CopyAndScaleTexture(GLuint texture, 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Size& src_size, 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Size& dst_size, 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool vertically_flip_texture, 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScalerQuality quality); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the shader compiled from the source. 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint CompileShaderFromSource(const GLchar* source, GLenum type); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Copies all pixels from |previous_texture| into |texture| that are 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // inside the region covered by |old_damage| but not part of |new_damage|. 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CopySubBufferDamage(GLuint texture, 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint previous_texture, 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkRegion& new_damage, 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkRegion& old_damage); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Simply creates a texture. 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint CreateTexture(); 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Deletes a texture. 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DeleteTexture(GLuint texture_id); 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Insert a sync point into the GL command buffer. 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 InsertSyncPoint(); 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Wait for the sync point before executing further GL commands. 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void WaitSyncPoint(uint32 sync_point); 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates a mailbox holder that is attached to the given texture id, with a 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // sync point to wait on before using the mailbox. Returns a holder with an 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // empty mailbox on failure. 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Note the texture is assumed to be GL_TEXTURE_2D. 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu::MailboxHolder ProduceMailboxHolderFromTexture(GLuint texture_id); 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Creates a texture and consumes a mailbox into it. Returns 0 on failure. 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Note the mailbox is assumed to be GL_TEXTURE_2D. 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 sync_point); 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Resizes the texture's size to |size|. 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ResizeTexture(GLuint texture, const gfx::Size& size); 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Copies the framebuffer data given in |rect| to |texture|. 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect); 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Copies the all framebuffer data to |texture|. |size| specifies the 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // size of the framebuffer. 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CopyTextureFullImage(GLuint texture, const gfx::Size& size); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Flushes GL commands. 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Flush(); 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // A scaler will cache all intermediate textures and programs 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // needed to scale from a specified size to a destination size. 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If the source or destination sizes changes, you must create 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // a new scaler. 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) class CONTENT_EXPORT ScalerInterface { 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScalerInterface() {} 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~ScalerInterface() {} 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that the src_texture will have the min/mag filter set to GL_LINEAR 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and wrap_s/t set to CLAMP_TO_EDGE in this call. 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Scale(GLuint source_texture, GLuint dest_texture) = 0; 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual const gfx::Size& SrcSize() = 0; 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual const gfx::Rect& SrcSubrect() = 0; 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual const gfx::Size& DstSize() = 0; 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) }; 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that the quality may be adjusted down if texture 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allocations fail or hardware doesn't support the requtested 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // quality. Note that ScalerQuality enum is arranged in 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // numerical order for simplicity. 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ScalerInterface* CreateScaler(ScalerQuality quality, 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Size& src_size, 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Rect& src_subrect, 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Size& dst_size, 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool vertically_flip_texture, 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool swizzle); 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Create a readback pipeline that will scale a subsection of the source 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // texture, then convert it to YUV422 planar form and then read back that. 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This reduces the amount of memory read from GPU to CPU memory by a factor 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 2.6, which can be quite handy since readbacks have very limited speed 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // on some platforms. All values in |dst_size| and |dst_subrect| must be 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // a multiple of two. If |use_mrt| is true, the pipeline will try to optimize 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the YUV conversion using the multi-render-target extension. |use_mrt| 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // should only be set to false for testing. 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadbackYUVInterface* CreateReadbackPipelineYUV(ScalerQuality quality, 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Size& src_size, 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& src_subrect, 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Size& dst_size, 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& dst_subrect, 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool flip_vertically, 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool use_mrt); 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Returns the maximum number of draw buffers available, 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 0 if GL_EXT_draw_buffers is not available. 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLint MaxDrawBuffers(); 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Checks whether the readbback is supported for texture with the 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // matching config. This doesnt check for cross format readbacks. 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool IsReadbackConfigSupported(SkColorType texture_format); 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected: 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class CopyTextureToImpl; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates |copy_texture_to_impl_| if NULL. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitCopyTextToImpl(); 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Creates |scaler_impl_| if NULL. 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void InitScalerImpl(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch enum ReadbackSwizzle { 336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kSwizzleNone = 0, 337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kSwizzleBGRA 338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }; 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu::gles2::GLES2Interface* gl_; 3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gpu::ContextSupport* context_support_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_; 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<GLHelperScaling> scaler_impl_; 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GLHelperReadbackSupport> readback_support_; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GLHelper); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Similar to a ScalerInterface, a yuv readback pipeline will 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// cache a scaler and all intermediate textures and frame buffers 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// needed to scale, crop, letterbox and read back a texture from 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// the GPU into CPU-accessible RAM. A single readback pipeline 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// can handle multiple outstanding readbacks at the same time, but 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// if the source or destination sizes change, you'll need to create 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// a new readback pipeline. 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CONTENT_EXPORT ReadbackYUVInterface { 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ReadbackYUVInterface() {} 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~ReadbackYUVInterface() {} 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Note that |target| must use YV12 format. 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void ReadbackYUV(const gpu::Mailbox& mailbox, 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 sync_point, 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<media::VideoFrame>& target, 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Callback<void(bool)>& callback) = 0; 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual GLHelper::ScalerInterface* scaler() = 0; 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 372