Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #include "content/browser/compositor/software_output_device_mac.h" | 7 #include "content/browser/compositor/software_output_device_mac.h" |
| 8 | 8 |
| 9 #include "base/mac/foundation_util.h" | |
| 10 #include "third_party/skia/include/core/SkCanvas.h" | |
| 9 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" | 11 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" |
| 10 #include "ui/compositor/compositor.h" | 12 #include "ui/compositor/compositor.h" |
| 13 #include "ui/gfx/skia_util.h" | |
| 11 | 14 |
| 12 namespace content { | 15 namespace content { |
| 13 | 16 |
| 14 SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor) | 17 SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor) |
| 15 : compositor_(compositor) { | 18 : compositor_(compositor), scale_factor_(1), current_index_(0) {} |
| 16 } | |
| 17 | 19 |
| 18 SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() { | 20 SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() { |
| 19 } | 21 } |
| 20 | 22 |
| 23 void SoftwareOutputDeviceMac::Resize(const gfx::Size& pixel_size, | |
| 24 float scale_factor) { | |
| 25 if (pixel_size_ == pixel_size && scale_factor_ == scale_factor) | |
| 26 return; | |
| 27 | |
| 28 pixel_size_ = pixel_size; | |
| 29 scale_factor_ = scale_factor; | |
| 30 | |
| 31 DiscardBackbuffer(); | |
| 32 } | |
| 33 | |
| 34 void SoftwareOutputDeviceMac::CopyPreviousBufferDamage( | |
| 35 const gfx::Rect& new_damage_rect) { | |
| 36 TRACE_EVENT0("browser", "CopyPreviousBufferDamage"); | |
| 37 | |
| 38 // The region to copy is the region drawn last frame, minus the region that | |
| 39 // is drawn this frame. | |
| 40 SkRegion copy_region( | |
| 41 SkRegion(gfx::RectToSkIRect(previous_buffer_damage_rect_))); | |
| 42 bool copy_region_nonempty = copy_region.op( | |
| 43 gfx::RectToSkIRect(new_damage_rect), SkRegion::kDifference_Op); | |
| 44 previous_buffer_damage_rect_ = new_damage_rect; | |
| 45 | |
| 46 if (!copy_region_nonempty) | |
| 47 return; | |
| 48 | |
| 49 { | |
| 50 TRACE_EVENT0("browser", "IOSurfaceLock"); | |
| 51 IOReturn io_result = IOSurfaceLock( | |
| 52 io_surfaces_[!current_index_], | |
| 53 kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); | |
| 54 if (io_result) { | |
| 55 DLOG(ERROR) << "Failed to lock previous IOSurface " << io_result; | |
| 56 return; | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 uint8_t* pixels = reinterpret_cast<uint8_t*>( | |
| 61 IOSurfaceGetBaseAddress(io_surfaces_[!current_index_])); | |
| 62 size_t pitch = IOSurfaceGetBytesPerRow(io_surfaces_[!current_index_]); | |
| 63 size_t bytes_per_element = 4; | |
| 64 for (SkRegion::Iterator it(copy_region); !it.done(); it.next()) { | |
| 65 const SkIRect& rect = it.rect(); | |
| 66 canvas_->writePixels( | |
| 67 SkImageInfo::MakeN32Premul(rect.width(), rect.height()), | |
| 68 pixels + bytes_per_element * rect.x() + pitch * rect.y(), pitch, | |
| 69 rect.x(), rect.y()); | |
| 70 } | |
| 71 | |
| 72 { | |
| 73 TRACE_EVENT0("browser", "IOSurfaceUnlock"); | |
| 74 IOReturn io_result = IOSurfaceUnlock( | |
| 75 io_surfaces_[!current_index_], | |
| 76 kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); | |
| 77 if (io_result) | |
| 78 DLOG(ERROR) << "Failed to unlock previous IOSurface " << io_result; | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 SkCanvas* SoftwareOutputDeviceMac::BeginPaint( | |
| 83 const gfx::Rect& new_damage_rect) { | |
| 84 for (int i = 0; i < 2; ++i) { | |
| 85 if (!io_surfaces_[i]) { | |
| 86 TRACE_EVENT0("browser", "IOSurfaceCreate"); | |
| 87 unsigned pixelFormat = 'BGRA'; | |
| 88 unsigned bytesPerElement = 4; | |
| 89 NSDictionary* options = @{ | |
| 90 (id) kIOSurfaceWidth : @(pixel_size_.width()), (id) | |
| 91 kIOSurfaceHeight : @(pixel_size_.height()), (id) | |
| 92 kIOSurfacePixelFormat : @(pixelFormat), (id) | |
| 93 kIOSurfaceBytesPerElement : @(bytesPerElement), | |
|
Avi (use Gerrit)
2015/10/23 19:41:58
What is this formatting? Please don't tell me that
ccameron
2015/10/23 19:50:29
I think it might have been "git cl format" ... but
| |
| 94 }; | |
| 95 io_surfaces_[i].reset(IOSurfaceCreate( | |
| 96 base::mac::CFCast<CFDictionaryRef>(options))); | |
| 97 } | |
| 98 if (!io_surfaces_[i]) { | |
| 99 DLOG(ERROR) << "Failed to allocateIOSurface"; | |
| 100 return nullptr; | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 { | |
| 105 TRACE_EVENT0("browser", "IOSurfaceLock"); | |
| 106 IOReturn io_result = IOSurfaceLock(io_surfaces_[current_index_], | |
| 107 kIOSurfaceLockAvoidSync, nullptr); | |
| 108 if (io_result) { | |
| 109 DLOG(ERROR) << "Failed to lock IOSurface " << io_result; | |
| 110 return nullptr; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 SkPMColor* pixels = reinterpret_cast<SkPMColor*>( | |
| 115 IOSurfaceGetBaseAddress(io_surfaces_[current_index_])); | |
| 116 size_t pitch = IOSurfaceGetBytesPerRow(io_surfaces_[current_index_]); | |
| 117 | |
| 118 canvas_ = skia::AdoptRef(SkCanvas::NewRasterDirectN32( | |
| 119 pixel_size_.width(), pixel_size_.height(), pixels, pitch)); | |
| 120 | |
| 121 CopyPreviousBufferDamage(new_damage_rect); | |
| 122 return canvas_.get(); | |
| 123 } | |
| 124 | |
| 21 void SoftwareOutputDeviceMac::EndPaint() { | 125 void SoftwareOutputDeviceMac::EndPaint() { |
| 22 SoftwareOutputDevice::EndPaint(); | 126 SoftwareOutputDevice::EndPaint(); |
| 23 ui::AcceleratedWidgetMacGotSoftwareFrame( | 127 { |
| 24 compositor_->widget(), scale_factor_, surface_->getCanvas()); | 128 TRACE_EVENT0("browser", "IOSurfaceUnlock"); |
| 129 IOReturn io_result = IOSurfaceUnlock(io_surfaces_[current_index_], | |
| 130 kIOSurfaceLockAvoidSync, nullptr); | |
| 131 if (io_result) | |
| 132 DLOG(ERROR) << "Failed to unlock IOSurface " << io_result; | |
| 133 } | |
| 134 | |
| 135 canvas_ = nullptr; | |
| 136 ui::AcceleratedWidgetMacGotIOSurfaceFrame(compositor_->widget(), | |
| 137 io_surfaces_[current_index_], | |
| 138 pixel_size_, scale_factor_, false); | |
| 139 | |
| 140 current_index_ = !current_index_; | |
| 25 } | 141 } |
| 26 | 142 |
| 143 void SoftwareOutputDeviceMac::DiscardBackbuffer() { | |
| 144 for (int i = 0; i < 2; ++i) | |
| 145 io_surfaces_[i].reset(); | |
| 146 } | |
| 147 | |
| 148 void SoftwareOutputDeviceMac::EnsureBackbuffer() {} | |
| 149 | |
| 27 } // namespace content | 150 } // namespace content |
| OLD | NEW |