Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: content/browser/renderer_host/compositing_iosurface_mac.mm

Issue 13749002: Cache OpenGL textures and other objects in CompositingIOSurfaceMac copy/transform code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tweaks, per nick@'s comments. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/compositing_iosurface_mac.h" 5 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
6 6
7 #include <OpenGL/CGLRenderers.h> 7 #include <OpenGL/CGLRenderers.h>
8 #include <OpenGL/OpenGL.h> 8 #include <OpenGL/OpenGL.h>
9 #include <vector>
10 9
11 #include "base/bind.h" 10 #include "base/bind.h"
12 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
13 #include "base/command_line.h" 12 #include "base/command_line.h"
14 #include "base/debug/trace_event.h" 13 #include "base/debug/trace_event.h"
15 #include "base/logging.h" 14 #include "base/logging.h"
16 #include "base/mac/mac_util.h" 15 #include "base/mac/mac_util.h"
17 #include "base/message_loop.h" 16 #include "base/message_loop.h"
18 #include "base/threading/platform_thread.h" 17 #include "base/threading/platform_thread.h"
19 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 18 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 const CVTimeStamp* output_time, 155 const CVTimeStamp* output_time,
157 CVOptionFlags flags_in, 156 CVOptionFlags flags_in,
158 CVOptionFlags* flags_out, 157 CVOptionFlags* flags_out,
159 void* context) { 158 void* context) {
160 CompositingIOSurfaceMac* surface = 159 CompositingIOSurfaceMac* surface =
161 static_cast<CompositingIOSurfaceMac*>(context); 160 static_cast<CompositingIOSurfaceMac*>(context);
162 surface->DisplayLinkTick(display_link, output_time); 161 surface->DisplayLinkTick(display_link, output_time);
163 return kCVReturnSuccess; 162 return kCVReturnSuccess;
164 } 163 }
165 164
166 CompositingIOSurfaceMac::CopyContext::CopyContext() 165 CompositingIOSurfaceMac::CopyContext::CopyContext(
167 : num_outputs(0), 166 const scoped_refptr<CompositingIOSurfaceContext>& context)
167 : transformer(new CompositingIOSurfaceTransformer(
168 GL_TEXTURE_RECTANGLE_ARB, true, context->shader_program_cache())),
169 num_outputs(0),
168 fence(0), 170 fence(0),
169 cycles_elapsed(0) { 171 cycles_elapsed(0) {
170 memset(output_textures, 0, sizeof(output_textures)); 172 memset(output_textures, 0, sizeof(output_textures));
171 memset(frame_buffers, 0, sizeof(frame_buffers)); 173 memset(frame_buffers, 0, sizeof(frame_buffers));
172 memset(pixel_buffers, 0, sizeof(pixel_buffers)); 174 memset(pixel_buffers, 0, sizeof(pixel_buffers));
173 } 175 }
174 176
175 CompositingIOSurfaceMac::CopyContext::~CopyContext() { 177 CompositingIOSurfaceMac::CopyContext::~CopyContext() {
178 DCHECK_EQ(frame_buffers[0], 0u) << "Failed to call ReleaseCachedGLObjects().";
176 } 179 }
177 180
178 void CompositingIOSurfaceMac::CopyContext::CleanUp() { 181 void CompositingIOSurfaceMac::CopyContext::ReleaseCachedGLObjects() {
179 glDeleteFramebuffersEXT(num_outputs, frame_buffers); CHECK_GL_ERROR(); 182 // No outstanding callbacks should be pending.
180 glDeleteTextures(num_outputs, output_textures); 183 DCHECK(map_buffer_callback.is_null());
181 CHECK_GL_ERROR(); 184 DCHECK(done_callback.is_null());
182 185
183 // For an asynchronous read-back, there are more objects to delete: 186 // For an asynchronous read-back, there are more objects to delete:
184 if (fence) { 187 if (fence) {
185 glDeleteBuffers(num_outputs, pixel_buffers); 188 glDeleteBuffers(arraysize(pixel_buffers), pixel_buffers); CHECK_GL_ERROR();
186 CHECK_GL_ERROR(); 189 memset(pixel_buffers, 0, sizeof(pixel_buffers));
187 glDeleteFencesAPPLE(1, &fence); CHECK_GL_ERROR(); 190 glDeleteFencesAPPLE(1, &fence); CHECK_GL_ERROR();
191 fence = 0;
192 }
193
194 glDeleteFramebuffersEXT(arraysize(frame_buffers), frame_buffers);
195 CHECK_GL_ERROR();
196 memset(frame_buffers, 0, sizeof(frame_buffers));
197
198 // Note: |output_textures| are owned by the transformer.
199 if (transformer)
200 transformer->ReleaseCachedGLObjects();
201 }
202
203 void CompositingIOSurfaceMac::CopyContext::PrepareReadbackFramebuffers() {
204 for (int i = 0; i < num_outputs; ++i) {
205 if (!frame_buffers[i]) {
206 glGenFramebuffersEXT(1, &frame_buffers[i]); CHECK_GL_ERROR();
207 }
188 } 208 }
189 } 209 }
190 210
211 void CompositingIOSurfaceMac::CopyContext::PrepareForAsynchronousReadback() {
212 PrepareReadbackFramebuffers();
213 if (!fence) {
214 glGenFencesAPPLE(1, &fence); CHECK_GL_ERROR();
215 }
216 for (int i = 0; i < num_outputs; ++i) {
217 if (!pixel_buffers[i]) {
218 glGenBuffersARB(1, &pixel_buffers[i]); CHECK_GL_ERROR();
219 }
220 }
221 }
222
223
191 // static 224 // static
192 CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create( 225 CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create(
193 int window_number, 226 int window_number,
194 SurfaceOrder surface_order) { 227 SurfaceOrder surface_order) {
195 TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create"); 228 TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create");
196 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 229 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
197 if (!io_surface_support) { 230 if (!io_surface_support) {
198 LOG(WARNING) << "No IOSurface support"; 231 LOG(WARNING) << "No IOSurface support";
199 return NULL; 232 return NULL;
200 } 233 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 290
258 // Stop display link for now, it will be started when needed during Draw. 291 // Stop display link for now, it will be started when needed during Draw.
259 StopDisplayLink(); 292 StopDisplayLink();
260 } 293 }
261 294
262 void CompositingIOSurfaceMac::SwitchToContextOnNewWindow(int window_number) { 295 void CompositingIOSurfaceMac::SwitchToContextOnNewWindow(int window_number) {
263 if (window_number == context_->window_number()) 296 if (window_number == context_->window_number())
264 return; 297 return;
265 298
266 // Asynchronous copies must complete in the same context they started in, 299 // Asynchronous copies must complete in the same context they started in,
267 // defer updating the GL context to the new window until the copy finishes. 300 // defer updating the GL context to the new window until the copy finishes and
301 // all outstanding CopyContexts are destroyed.
268 if (!copy_requests_.empty()) 302 if (!copy_requests_.empty())
269 return; 303 return;
304 if (!copy_context_pool_.empty()) {
305 CGLSetCurrentContext(context_->cgl_context());
306 DestroyAllCopyContextsWithinContext();
307 CGLSetCurrentContext(0);
308 }
270 309
271 scoped_refptr<CompositingIOSurfaceContext> new_context = 310 scoped_refptr<CompositingIOSurfaceContext> new_context =
272 CompositingIOSurfaceContext::Get(window_number, 311 CompositingIOSurfaceContext::Get(window_number,
273 context_->surface_order()); 312 context_->surface_order());
274 if (!new_context) 313 if (!new_context)
275 return; 314 return;
276 315
277 transformer_.reset(nil);
278 context_ = new_context; 316 context_ = new_context;
279 } 317 }
280 318
281 bool CompositingIOSurfaceMac::is_vsync_disabled() const { 319 bool CompositingIOSurfaceMac::is_vsync_disabled() const {
282 return context_->is_vsync_disabled(); 320 return context_->is_vsync_disabled();
283 } 321 }
284 322
285 void CompositingIOSurfaceMac::GetVSyncParameters(base::TimeTicks* timebase, 323 void CompositingIOSurfaceMac::GetVSyncParameters(base::TimeTicks* timebase,
286 uint32* interval_numerator, 324 uint32* interval_numerator,
287 uint32* interval_denominator) { 325 uint32* interval_denominator) {
288 base::AutoLock lock(lock_); 326 base::AutoLock lock(lock_);
289 *timebase = vsync_timebase_; 327 *timebase = vsync_timebase_;
290 *interval_numerator = vsync_interval_numerator_; 328 *interval_numerator = vsync_interval_numerator_;
291 *interval_denominator = vsync_interval_denominator_; 329 *interval_denominator = vsync_interval_denominator_;
292 } 330 }
293 331
294 CompositingIOSurfaceMac::~CompositingIOSurfaceMac() { 332 CompositingIOSurfaceMac::~CompositingIOSurfaceMac() {
295 FailAllCopies(); 333 FailAllCopies();
296 CVDisplayLinkRelease(display_link_); 334 CVDisplayLinkRelease(display_link_);
297 CGLSetCurrentContext(context_->cgl_context()); 335 CGLSetCurrentContext(context_->cgl_context());
298 CleanupAllCopiesWithinContext(); 336 DestroyAllCopyContextsWithinContext();
299 UnrefIOSurfaceWithContextCurrent(); 337 UnrefIOSurfaceWithContextCurrent();
300 CGLSetCurrentContext(0); 338 CGLSetCurrentContext(0);
301 context_ = nil; 339 context_ = nil;
302 } 340 }
303 341
304 void CompositingIOSurfaceMac::SetIOSurface(uint64 io_surface_handle, 342 void CompositingIOSurfaceMac::SetIOSurface(uint64 io_surface_handle,
305 const gfx::Size& size) { 343 const gfx::Size& size) {
306 pixel_io_surface_size_ = size; 344 pixel_io_surface_size_ = size;
307 CGLSetCurrentContext(context_->cgl_context()); 345 CGLSetCurrentContext(context_->cgl_context());
308 MapIOSurfaceToTexture(io_surface_handle); 346 MapIOSurfaceToTexture(io_surface_handle);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 DCHECK(!done_callback.is_null()); 755 DCHECK(!done_callback.is_null());
718 756
719 // TODO(miu): Forcing synchronous copy for M27. Will work on fixing the 757 // TODO(miu): Forcing synchronous copy for M27. Will work on fixing the
720 // desired asynchronous method for M28. http://crbug.com/223326 758 // desired asynchronous method for M28. http://crbug.com/223326
721 const bool async_copy = false; 759 const bool async_copy = false;
722 TRACE_EVENT2( 760 TRACE_EVENT2(
723 "browser", "CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext", 761 "browser", "CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext",
724 "output", bitmap_output ? "SkBitmap (ARGB)" : "VideoFrame (YV12)", 762 "output", bitmap_output ? "SkBitmap (ARGB)" : "VideoFrame (YV12)",
725 "async_readback", async_copy); 763 "async_readback", async_copy);
726 764
765 CopyContext* copy_context;
766 if (copy_context_pool_.empty()) {
767 // TODO(miu): Determine appropriate limit once new async copy approach is
768 // put in place.
769 if (copy_requests_.size() >= 3)
770 return base::Bind(done_callback, false);
771 copy_context = new CopyContext(context_);
772 } else {
773 copy_context = copy_context_pool_.back();
774 copy_context_pool_.pop_back();
775 }
776
727 // Set up source texture, bound to the GL_TEXTURE_RECTANGLE_ARB target. 777 // Set up source texture, bound to the GL_TEXTURE_RECTANGLE_ARB target.
728 if (!MapIOSurfaceToTexture(io_surface_handle_)) 778 if (!MapIOSurfaceToTexture(io_surface_handle_))
729 return base::Bind(done_callback, false); 779 return base::Bind(done_callback, false);
730 780
731 // Create the transformer_ on first use.
732 if (!transformer_) {
733 transformer_.reset(new CompositingIOSurfaceTransformer(
734 GL_TEXTURE_RECTANGLE_ARB,
735 true,
736 context_->shader_program_cache()));
737 }
738
739 // Send transform commands to the GPU. 781 // Send transform commands to the GPU.
740 const gfx::Rect src_rect = IntersectWithIOSurface(src_pixel_subrect, 782 const gfx::Rect src_rect = IntersectWithIOSurface(src_pixel_subrect,
741 src_scale_factor); 783 src_scale_factor);
742 CopyContext copy_context; 784 copy_context->num_outputs = 0;
743 if (bitmap_output) { 785 if (bitmap_output) {
744 if (transformer_->ResizeBilinear(texture_, src_rect, dst_pixel_rect.size(), 786 if (copy_context->transformer->ResizeBilinear(
745 &copy_context.output_textures[0])) { 787 texture_, src_rect, dst_pixel_rect.size(),
746 copy_context.num_outputs = 1; 788 &copy_context->output_textures[0])) {
747 copy_context.output_texture_sizes[0] = dst_pixel_rect.size(); 789 copy_context->num_outputs = 1;
790 copy_context->output_texture_sizes[0] = dst_pixel_rect.size();
748 } 791 }
749 } else { 792 } else {
750 if (transformer_->TransformRGBToYV12( 793 if (copy_context->transformer->TransformRGBToYV12(
751 texture_, src_rect, dst_pixel_rect.size(), 794 texture_, src_rect, dst_pixel_rect.size(),
752 &copy_context.output_textures[0], 795 &copy_context->output_textures[0],
753 &copy_context.output_textures[1], 796 &copy_context->output_textures[1],
754 &copy_context.output_textures[2], 797 &copy_context->output_textures[2],
755 &copy_context.output_texture_sizes[0], 798 &copy_context->output_texture_sizes[0],
756 &copy_context.output_texture_sizes[1])) { 799 &copy_context->output_texture_sizes[1])) {
757 copy_context.num_outputs = 3; 800 copy_context->num_outputs = 3;
758 copy_context.output_texture_sizes[2] = 801 copy_context->output_texture_sizes[2] =
759 copy_context.output_texture_sizes[1]; 802 copy_context->output_texture_sizes[1];
760 } 803 }
761 } 804 }
762 if (!copy_context.num_outputs) 805 if (!copy_context->num_outputs)
763 return base::Bind(done_callback, false); 806 return base::Bind(done_callback, false);
764 807
765 // In the asynchronous case, issue commands to the GPU and return a null 808 // In the asynchronous case, issue commands to the GPU and return a null
766 // closure here. In the synchronous case, perform a blocking readback and 809 // closure here. In the synchronous case, perform a blocking readback and
767 // return a callback to be run outside the CGL context to indicate success. 810 // return a callback to be run outside the CGL context to indicate success.
768 if (async_copy) { 811 if (async_copy) {
769 copy_context.done_callback = done_callback; 812 copy_context->done_callback = done_callback;
770 AsynchronousReadbackForCopy( 813 AsynchronousReadbackForCopy(
771 dst_pixel_rect, called_within_draw, &copy_context, bitmap_output, 814 dst_pixel_rect, called_within_draw, copy_context, bitmap_output,
772 video_frame_output); 815 video_frame_output);
773 copy_requests_.push_back(copy_context); 816 copy_requests_.push_back(copy_context);
774 if (!finish_copy_timer_.IsRunning()) 817 if (!finish_copy_timer_.IsRunning())
775 finish_copy_timer_.Reset(); 818 finish_copy_timer_.Reset();
776 return base::Closure(); 819 return base::Closure();
777 } else { 820 } else {
778 const bool success = SynchronousReadbackForCopy( 821 const bool success = SynchronousReadbackForCopy(
779 dst_pixel_rect, &copy_context, bitmap_output, video_frame_output); 822 dst_pixel_rect, copy_context, bitmap_output, video_frame_output);
780 return base::Bind(done_callback, success); 823 return base::Bind(done_callback, success);
781 } 824 }
782 } 825 }
783 826
784 void CompositingIOSurfaceMac::AsynchronousReadbackForCopy( 827 void CompositingIOSurfaceMac::AsynchronousReadbackForCopy(
785 const gfx::Rect& dst_pixel_rect, 828 const gfx::Rect& dst_pixel_rect,
786 bool called_within_draw, 829 bool called_within_draw,
787 CopyContext* copy_context, 830 CopyContext* copy_context,
788 const SkBitmap* bitmap_output, 831 const SkBitmap* bitmap_output,
789 const scoped_refptr<media::VideoFrame>& video_frame_output) { 832 const scoped_refptr<media::VideoFrame>& video_frame_output) {
790 glGenFencesAPPLE(1, &copy_context->fence); CHECK_GL_ERROR(); 833 copy_context->PrepareForAsynchronousReadback();
791 834
792 // Copy the textures to a PBO. 835 // Copy the textures to their corresponding PBO.
793 glGenFramebuffersEXT(copy_context->num_outputs, copy_context->frame_buffers);
794 CHECK_GL_ERROR();
795 glGenBuffersARB(copy_context->num_outputs, copy_context->pixel_buffers);
796 CHECK_GL_ERROR();
797 for (int i = 0; i < copy_context->num_outputs; ++i) { 836 for (int i = 0; i < copy_context->num_outputs; ++i) {
798 TRACE_EVENT1( 837 TRACE_EVENT1(
799 "browser", "CompositingIOSurfaceMac::AsynchronousReadbackForCopy", 838 "browser", "CompositingIOSurfaceMac::AsynchronousReadbackForCopy",
800 "plane", i); 839 "plane", i);
801 840
802 // Attach the output texture to the FBO. 841 // Attach the output texture to the FBO.
803 glBindFramebufferEXT( 842 glBindFramebufferEXT(
804 GL_READ_FRAMEBUFFER_EXT, copy_context->frame_buffers[i]); 843 GL_READ_FRAMEBUFFER_EXT, copy_context->frame_buffers[i]);
805 glFramebufferTexture2DEXT( 844 glFramebufferTexture2DEXT(
806 GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 845 GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
(...skipping 10 matching lines...) Expand all
817 glReadPixels(0, 0, 856 glReadPixels(0, 0,
818 copy_context->output_texture_sizes[i].width(), 857 copy_context->output_texture_sizes[i].width(),
819 copy_context->output_texture_sizes[i].height(), 858 copy_context->output_texture_sizes[i].height(),
820 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); CHECK_GL_ERROR(); 859 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); CHECK_GL_ERROR();
821 } 860 }
822 861
823 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); CHECK_GL_ERROR(); 862 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); CHECK_GL_ERROR();
824 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR(); 863 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
825 864
826 glSetFenceAPPLE(copy_context->fence); CHECK_GL_ERROR(); 865 glSetFenceAPPLE(copy_context->fence); CHECK_GL_ERROR();
866 copy_context->cycles_elapsed = 0;
827 867
828 // When this asynchronous copy happens in a draw operaton there is not need 868 // When this asynchronous copy happens in a draw operaton there is no need
829 // to explicitly flush because there will be a swap buffer and this flush 869 // to explicitly flush because there will be a swap buffer and this flush
830 // hurts performance. 870 // hurts performance.
831 if (!called_within_draw) { 871 if (!called_within_draw) {
832 glFlush(); CHECK_GL_ERROR(); 872 glFlush(); CHECK_GL_ERROR();
833 } 873 }
834 874
835 copy_context->map_buffer_callback = bitmap_output ? 875 copy_context->map_buffer_callback = bitmap_output ?
836 base::Bind(&MapBufferToSkBitmap, bitmap_output) : 876 base::Bind(&MapBufferToSkBitmap, bitmap_output) :
837 base::Bind(&MapBufferToVideoFrame, video_frame_output, dst_pixel_rect); 877 base::Bind(&MapBufferToVideoFrame, video_frame_output, dst_pixel_rect);
838 } 878 }
839 879
840 void CompositingIOSurfaceMac::FinishAllCopies() { 880 void CompositingIOSurfaceMac::FinishAllCopies() {
841 std::vector<base::Closure> done_callbacks; 881 std::vector<base::Closure> done_callbacks;
842 CGLSetCurrentContext(context_->cgl_context()); 882 CGLSetCurrentContext(context_->cgl_context());
843 FinishAllCopiesWithinContext(&done_callbacks); 883 FinishAllCopiesWithinContext(&done_callbacks);
844 CGLSetCurrentContext(0); 884 CGLSetCurrentContext(0);
845 for (size_t i = 0; i < done_callbacks.size(); ++i) 885 for (size_t i = 0; i < done_callbacks.size(); ++i)
846 done_callbacks[i].Run(); 886 done_callbacks[i].Run();
847 } 887 }
848 888
849 void CompositingIOSurfaceMac::FinishAllCopiesWithinContext( 889 void CompositingIOSurfaceMac::FinishAllCopiesWithinContext(
850 std::vector<base::Closure>* done_callbacks) { 890 std::vector<base::Closure>* done_callbacks) {
851 while (!copy_requests_.empty()) { 891 while (!copy_requests_.empty()) {
852 CopyContext& copy_context = copy_requests_.front(); 892 CopyContext* const copy_context = copy_requests_.front();
853 893
854 if (copy_context.fence) { 894 if (copy_context->fence) {
855 const bool copy_completed = glTestFenceAPPLE(copy_context.fence); 895 const bool copy_completed = glTestFenceAPPLE(copy_context->fence);
856 CHECK_GL_ERROR(); 896 CHECK_GL_ERROR();
857 897
858 if (!copy_completed && 898 if (!copy_completed &&
859 copy_context.cycles_elapsed < kFinishCopyRetryCycles) { 899 copy_context->cycles_elapsed < kFinishCopyRetryCycles) {
860 ++copy_context.cycles_elapsed; 900 ++copy_context->cycles_elapsed;
861 // This copy has not completed there is no need to test subsequent 901 // This copy has not completed there is no need to test subsequent
862 // requests. 902 // requests.
863 break; 903 break;
864 } 904 }
865 } 905 }
866 906
867 bool success = true; 907 bool success = true;
868 for (int i = 0; success && i < copy_context.num_outputs; ++i) { 908 for (int i = 0; success && i < copy_context->num_outputs; ++i) {
869 TRACE_EVENT1( 909 TRACE_EVENT1(
870 "browser", "CompositingIOSurfaceMac::FinishAllCopyWithinContext", 910 "browser", "CompositingIOSurfaceMac::FinishAllCopyWithinContext",
871 "plane", i); 911 "plane", i);
872 912
873 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, copy_context.pixel_buffers[i]); 913 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, copy_context->pixel_buffers[i]);
874 CHECK_GL_ERROR(); 914 CHECK_GL_ERROR();
875 915
876 void* buf = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); 916 void* buf = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
877 CHECK_GL_ERROR(); 917 CHECK_GL_ERROR();
878 success &= copy_context.map_buffer_callback.Run(buf, i); 918 success &= copy_context->map_buffer_callback.Run(buf, i);
879 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); CHECK_GL_ERROR(); 919 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); CHECK_GL_ERROR();
880 } 920 }
921 copy_context->map_buffer_callback.Reset();
922 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); CHECK_GL_ERROR();
881 923
882 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); CHECK_GL_ERROR();
883 copy_context.CleanUp();
884 done_callbacks->push_back(base::Bind(copy_context.done_callback, success));
885 copy_requests_.pop_front(); 924 copy_requests_.pop_front();
925 done_callbacks->push_back(base::Bind(copy_context->done_callback, success));
926 copy_context->done_callback.Reset();
927 copy_context_pool_.push_back(copy_context);
886 } 928 }
887 if (copy_requests_.empty()) 929 if (copy_requests_.empty())
888 finish_copy_timer_.Stop(); 930 finish_copy_timer_.Stop();
889 } 931 }
890 932
891 bool CompositingIOSurfaceMac::SynchronousReadbackForCopy( 933 bool CompositingIOSurfaceMac::SynchronousReadbackForCopy(
892 const gfx::Rect& dst_pixel_rect, 934 const gfx::Rect& dst_pixel_rect,
893 CopyContext* copy_context, 935 CopyContext* copy_context,
894 const SkBitmap* bitmap_output, 936 const SkBitmap* bitmap_output,
895 const scoped_refptr<media::VideoFrame>& video_frame_output) { 937 const scoped_refptr<media::VideoFrame>& video_frame_output) {
896 bool success = true; 938 bool success = true;
897 glGenFramebuffersEXT(copy_context->num_outputs, copy_context->frame_buffers); 939 copy_context->PrepareReadbackFramebuffers();
898 CHECK_GL_ERROR();
899 for (int i = 0; i < copy_context->num_outputs; ++i) { 940 for (int i = 0; i < copy_context->num_outputs; ++i) {
900 TRACE_EVENT1( 941 TRACE_EVENT1(
901 "browser", "CompositingIOSurfaceMac::SynchronousReadbackForCopy", 942 "browser", "CompositingIOSurfaceMac::SynchronousReadbackForCopy",
902 "plane", i); 943 "plane", i);
903 944
904 // Attach the output texture to the FBO. 945 // Attach the output texture to the FBO.
905 glBindFramebufferEXT( 946 glBindFramebufferEXT(
906 GL_READ_FRAMEBUFFER_EXT, copy_context->frame_buffers[i]); 947 GL_READ_FRAMEBUFFER_EXT, copy_context->frame_buffers[i]);
907 glFramebufferTexture2DEXT( 948 glFramebufferTexture2DEXT(
908 GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 949 GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 media::LetterboxYUV(video_frame_output, dst_pixel_rect); 996 media::LetterboxYUV(video_frame_output, dst_pixel_rect);
956 } else { 997 } else {
957 // Copy from temporary buffer and fully render the VideoFrame. 998 // Copy from temporary buffer and fully render the VideoFrame.
958 success &= MapBufferToVideoFrame(video_frame_output, dst_pixel_rect, 999 success &= MapBufferToVideoFrame(video_frame_output, dst_pixel_rect,
959 temp_readback_buffer.get(), i); 1000 temp_readback_buffer.get(), i);
960 } 1001 }
961 } 1002 }
962 } 1003 }
963 1004
964 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR(); 1005 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
965 copy_context->CleanUp(); 1006 copy_context_pool_.push_back(copy_context);
966 return success; 1007 return success;
967 } 1008 }
968 1009
969 void CompositingIOSurfaceMac::CleanupAllCopiesWithinContext() { 1010 void CompositingIOSurfaceMac::FailAllCopies() {
970 for (size_t i = 0; i < copy_requests_.size(); ++i) 1011 for (size_t i = 0; i < copy_requests_.size(); ++i) {
971 copy_requests_[i].CleanUp(); 1012 copy_requests_[i]->map_buffer_callback.Reset();
972 copy_requests_.clear(); 1013
1014 base::Callback<void(bool)>& done_callback =
1015 copy_requests_[i]->done_callback;
1016 if (!done_callback.is_null()) {
1017 done_callback.Run(false);
1018 done_callback.Reset();
1019 }
1020 }
973 } 1021 }
974 1022
975 void CompositingIOSurfaceMac::FailAllCopies() { 1023 void CompositingIOSurfaceMac::DestroyAllCopyContextsWithinContext() {
976 for (size_t i = 0; i < copy_requests_.size(); ++i) 1024 // Move all in-flight copies, if any, back into the pool. Then, destroy all
977 copy_requests_[i].done_callback.Run(false); 1025 // the CopyContexts in the pool.
1026 copy_context_pool_.insert(copy_context_pool_.end(),
1027 copy_requests_.begin(), copy_requests_.end());
1028 copy_requests_.clear();
1029 while (!copy_context_pool_.empty()) {
1030 scoped_ptr<CopyContext> copy_context(copy_context_pool_.back());
1031 copy_context_pool_.pop_back();
1032 copy_context->ReleaseCachedGLObjects();
1033 }
978 } 1034 }
979 1035
980 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( 1036 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface(
981 const gfx::Rect& rect, float scale_factor) const { 1037 const gfx::Rect& rect, float scale_factor) const {
982 return gfx::IntersectRects(rect, 1038 return gfx::IntersectRects(rect,
983 gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(io_surface_size_), 1039 gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(io_surface_size_),
984 scale_factor))); 1040 scale_factor)));
985 } 1041 }
986 1042
987 } // namespace content 1043 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698