| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/accelerated_surface_container_mac.h" | 5 #include "chrome/browser/renderer_host/accelerated_surface_container_mac.h" |
| 6 | 6 |
| 7 #include "app/surface/io_surface_support_mac.h" | 7 #include "app/surface/io_surface_support_mac.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "chrome/browser/renderer_host/accelerated_surface_container_manager_mac
.h" | 9 #include "chrome/browser/renderer_host/accelerated_surface_container_manager_mac
.h" |
| 10 #include "webkit/glue/plugins/webplugin.h" | 10 #include "webkit/glue/plugins/webplugin.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 was_painted_to_(false) { | 24 was_painted_to_(false) { |
| 25 } | 25 } |
| 26 | 26 |
| 27 AcceleratedSurfaceContainerMac::~AcceleratedSurfaceContainerMac() { | 27 AcceleratedSurfaceContainerMac::~AcceleratedSurfaceContainerMac() { |
| 28 } | 28 } |
| 29 | 29 |
| 30 void AcceleratedSurfaceContainerMac::SetSizeAndIOSurface( | 30 void AcceleratedSurfaceContainerMac::SetSizeAndIOSurface( |
| 31 int32 width, | 31 int32 width, |
| 32 int32 height, | 32 int32 height, |
| 33 uint64 io_surface_identifier) { | 33 uint64 io_surface_identifier) { |
| 34 surface_.reset(); | 34 // Ignore |io_surface_identifier|: The surface hasn't been painted to and |
| 35 surface_id_ = 0; | 35 // only contains garbage data. Update the surface in |set_was_painted_to()| |
| 36 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | 36 // instead. |
| 37 if (io_surface_support) { | 37 width_ = width; |
| 38 surface_.reset(io_surface_support->IOSurfaceLookup( | 38 height_ = height; |
| 39 static_cast<uint32>(io_surface_identifier))); | |
| 40 if (surface_.get()) | |
| 41 surface_id_ = io_surface_identifier; | |
| 42 EnqueueTextureForDeletion(); | |
| 43 width_ = width; | |
| 44 height_ = height; | |
| 45 } | |
| 46 } | 39 } |
| 47 | 40 |
| 48 void AcceleratedSurfaceContainerMac::SetSizeAndTransportDIB( | 41 void AcceleratedSurfaceContainerMac::SetSizeAndTransportDIB( |
| 49 int32 width, | 42 int32 width, |
| 50 int32 height, | 43 int32 height, |
| 51 TransportDIB::Handle transport_dib) { | 44 TransportDIB::Handle transport_dib) { |
| 52 if (TransportDIB::is_valid(transport_dib)) { | 45 if (TransportDIB::is_valid(transport_dib)) { |
| 53 transport_dib_.reset(TransportDIB::Map(transport_dib)); | 46 transport_dib_.reset(TransportDIB::Map(transport_dib)); |
| 54 EnqueueTextureForDeletion(); | 47 EnqueueTextureForDeletion(); |
| 55 width_ = width; | 48 width_ = width; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 // When using an IOSurface, the texture does not need to be repeatedly | 100 // When using an IOSurface, the texture does not need to be repeatedly |
| 108 // uploaded, just when we've been told we have to. | 101 // uploaded, just when we've been told we have to. |
| 109 if (io_surface_support && texture_needs_upload_) { | 102 if (io_surface_support && texture_needs_upload_) { |
| 110 DCHECK(surface_.get()); | 103 DCHECK(surface_.get()); |
| 111 glBindTexture(target, texture_); | 104 glBindTexture(target, texture_); |
| 112 // Don't think we need to identify a plane. | 105 // Don't think we need to identify a plane. |
| 113 GLuint plane = 0; | 106 GLuint plane = 0; |
| 114 io_surface_support->CGLTexImageIOSurface2D(context, | 107 io_surface_support->CGLTexImageIOSurface2D(context, |
| 115 target, | 108 target, |
| 116 GL_RGBA, | 109 GL_RGBA, |
| 117 width_, | 110 surface_width_, |
| 118 height_, | 111 surface_height_, |
| 119 GL_BGRA, | 112 GL_BGRA, |
| 120 GL_UNSIGNED_INT_8_8_8_8_REV, | 113 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 121 surface_.get(), | 114 surface_.get(), |
| 122 plane); | 115 plane); |
| 123 texture_needs_upload_ = false; | 116 texture_needs_upload_ = false; |
| 124 } | 117 } |
| 125 // If using TransportDIBs, the texture needs to be uploaded every frame. | 118 // If using TransportDIBs, the texture needs to be uploaded every frame. |
| 126 if (transport_dib_.get() != NULL) { | 119 if (transport_dib_.get() != NULL) { |
| 127 void* pixel_memory = transport_dib_->memory(); | 120 void* pixel_memory = transport_dib_->memory(); |
| 128 if (pixel_memory) { | 121 if (pixel_memory) { |
| 129 glBindTexture(target, texture_); | 122 glBindTexture(target, texture_); |
| 130 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Needed for NPOT textures. | 123 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Needed for NPOT textures. |
| 131 glTexSubImage2D(target, | 124 glTexSubImage2D(target, |
| 132 0, // mipmap level 0 | 125 0, // mipmap level 0 |
| 133 0, // x-offset | 126 0, // x-offset |
| 134 0, // y-offset | 127 0, // y-offset |
| 135 width_, | 128 width_, |
| 136 height_, | 129 height_, |
| 137 GL_BGRA, // The GPU plugin gave us BGRA pixels | 130 GL_BGRA, // The GPU plugin gave us BGRA pixels |
| 138 GL_UNSIGNED_INT_8_8_8_8_REV, | 131 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 139 pixel_memory); | 132 pixel_memory); |
| 140 } | 133 } |
| 141 } | 134 } |
| 142 | 135 |
| 143 if (texture_) { | 136 if (texture_) { |
| 137 int texture_width = io_surface_support ? surface_width_ : width_; |
| 138 int texture_height = io_surface_support ? surface_height_ : height_; |
| 139 |
| 144 // TODO(kbr): convert this to use only OpenGL ES 2.0 functionality. | 140 // TODO(kbr): convert this to use only OpenGL ES 2.0 functionality. |
| 145 | 141 |
| 146 // TODO(kbr): may need to pay attention to cutout rects. | 142 // TODO(kbr): may need to pay attention to cutout rects. |
| 147 int clipX = clipRect_.x(); | 143 int clipX = clipRect_.x(); |
| 148 int clipY = clipRect_.y(); | 144 int clipY = clipRect_.y(); |
| 149 int clipWidth = clipRect_.width(); | 145 int clipWidth = clipRect_.width(); |
| 150 int clipHeight = clipRect_.height(); | 146 int clipHeight = clipRect_.height(); |
| 151 | 147 |
| 148 if (clipX + clipWidth > texture_width) |
| 149 clipWidth = texture_width - clipX; |
| 150 if (clipY + clipHeight > texture_height) |
| 151 clipHeight = texture_height - clipY; |
| 152 |
| 152 if (opaque_) { | 153 if (opaque_) { |
| 153 // Pepper 3D's output is currently considered opaque even if the | 154 // Pepper 3D's output is currently considered opaque even if the |
| 154 // program draws pixels with alpha less than 1. In order to have | 155 // program draws pixels with alpha less than 1. In order to have |
| 155 // this effect, we need to drop the alpha channel of the input, | 156 // this effect, we need to drop the alpha channel of the input, |
| 156 // replacing it with alpha = 1. | 157 // replacing it with alpha = 1. |
| 157 | 158 |
| 158 // First fill the rectangle with alpha=1. | 159 // First fill the rectangle with alpha=1. |
| 159 glColorMask(false, false, false, true); | 160 glColorMask(false, false, false, true); |
| 160 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); | 161 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); |
| 161 glBegin(GL_TRIANGLE_STRIP); | 162 glBegin(GL_TRIANGLE_STRIP); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 172 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 173 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
| 173 } else { | 174 } else { |
| 174 glColorMask(true, true, true, true); | 175 glColorMask(true, true, true, true); |
| 175 } | 176 } |
| 176 | 177 |
| 177 // Draw the color channels from the incoming texture. | 178 // Draw the color channels from the incoming texture. |
| 178 glBindTexture(target, texture_); | 179 glBindTexture(target, texture_); |
| 179 glEnable(target); | 180 glEnable(target); |
| 180 glBegin(GL_TRIANGLE_STRIP); | 181 glBegin(GL_TRIANGLE_STRIP); |
| 181 | 182 |
| 182 glTexCoord2f(clipX, height_ - clipY); | 183 glTexCoord2f(clipX, texture_height - clipY); |
| 183 glVertex3f(0, 0, 0); | 184 glVertex3f(0, 0, 0); |
| 184 | 185 |
| 185 glTexCoord2f(clipX + clipWidth, height_ - clipY); | 186 glTexCoord2f(clipX + clipWidth, texture_height - clipY); |
| 186 glVertex3f(clipWidth, 0, 0); | 187 glVertex3f(clipWidth, 0, 0); |
| 187 | 188 |
| 188 glTexCoord2f(clipX, height_ - clipY - clipHeight); | 189 glTexCoord2f(clipX, texture_height - clipY - clipHeight); |
| 189 glVertex3f(0, clipHeight, 0); | 190 glVertex3f(0, clipHeight, 0); |
| 190 | 191 |
| 191 glTexCoord2f(clipX + clipWidth, height_ - clipY - clipHeight); | 192 glTexCoord2f(clipX + clipWidth, texture_height - clipY - clipHeight); |
| 192 glVertex3f(clipWidth, clipHeight, 0); | 193 glVertex3f(clipWidth, clipHeight, 0); |
| 193 | 194 |
| 194 glEnd(); | 195 glEnd(); |
| 195 glDisable(target); | 196 glDisable(target); |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 | 199 |
| 199 void AcceleratedSurfaceContainerMac::set_was_painted_to(uint64 surface_id) { | 200 void AcceleratedSurfaceContainerMac::set_was_painted_to(uint64 surface_id) { |
| 200 if (surface_id) { | 201 if (surface_id && (!surface_ || surface_id != surface_id_)) { |
| 201 // Check that only the most current IOSurface allocated for this container | 202 // Keep the surface that was most recently painted to around. |
| 202 // is painted to. | 203 if (IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize()) { |
| 203 DCHECK(surface_); | 204 CFTypeRef surface = io_surface_support->IOSurfaceLookup( |
| 204 DCHECK_EQ(surface_id, surface_id_); | 205 static_cast<uint32>(surface_id)); |
| 206 // Can fail if IOSurface with that ID was already released by the |
| 207 // gpu process or the plugin process. We will get a |set_was_painted_to()| |
| 208 // message with a new surface soon in that case. |
| 209 if (surface) { |
| 210 surface_.reset(surface); |
| 211 surface_id_ = surface_id; |
| 212 surface_width_ = io_surface_support->IOSurfaceGetWidth(surface_); |
| 213 surface_height_ = io_surface_support->IOSurfaceGetHeight(surface_); |
| 214 EnqueueTextureForDeletion(); |
| 215 } |
| 216 } |
| 205 } | 217 } |
| 206 was_painted_to_ = true; | 218 was_painted_to_ = true; |
| 207 } | 219 } |
| 208 | 220 |
| 209 void AcceleratedSurfaceContainerMac::EnqueueTextureForDeletion() { | 221 void AcceleratedSurfaceContainerMac::EnqueueTextureForDeletion() { |
| 210 if (texture_) { | 222 if (texture_) { |
| 211 DCHECK(texture_pending_deletion_ == 0); | 223 DCHECK(texture_pending_deletion_ == 0); |
| 212 texture_pending_deletion_ = texture_; | 224 texture_pending_deletion_ = texture_; |
| 213 texture_ = 0; | 225 texture_ = 0; |
| 214 } | 226 } |
| 215 } | 227 } |
| 216 | 228 |
| OLD | NEW |