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

Side by Side Diff: Source/core/platform/graphics/gpu/DrawingBuffer.cpp

Issue 17859003: Allow DrawingBuffer to present to a bitmap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010, Google Inc. All rights reserved. 2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 return textureId; 169 return textureId;
170 } 170 }
171 171
172 WebKit::WebGraphicsContext3D* DrawingBuffer::context() 172 WebKit::WebGraphicsContext3D* DrawingBuffer::context()
173 { 173 {
174 if (!m_context) 174 if (!m_context)
175 return 0; 175 return 0;
176 return m_context->webContext(); 176 return m_context->webContext();
177 } 177 }
178 178
179 bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox ) 179 bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox , bool bitmap)
180 { 180 {
181 if (!m_context || !m_contentsChanged || !m_lastColorBuffer) 181 if (!m_context || !m_contentsChanged || !m_lastColorBuffer)
182 return false; 182 return false;
183 183
184 m_context->makeContextCurrent(); 184 m_context->makeContextCurrent();
185 185
186 // Resolve the multisampled buffer into the texture referenced by m_lastColo rBuffer mailbox. 186 // Resolve the multisampled buffer into the texture referenced by m_lastColo rBuffer mailbox.
187 if (multisample()) 187 if (multisample())
188 commit(); 188 commit();
189 189
190 if (bitmap) {
191 SkBitmap* bitmap = &m_lastColorBuffer->mailbox.bitmap;
192 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
193 if (bitmap->width() != size().width()
194 || bitmap->height() != size().height()) {
195 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size().width(), size( ).height(), 0);
196 bitmap->allocPixels();
197 }
198 m_lastColorBuffer->mailbox.size = size();
199
200 SkAutoLockPixels bitmapLock(*bitmap);
201
202 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()) ;
203 m_context->readPixels(0, 0, size().width(), size().height(), GraphicsCon text3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
Ken Russell (switch to Gerrit) 2013/06/27 13:41:02 We'd better be careful that the user hasn't set th
204 for (int i = 0; i < size().width() * size().height() * 4; i += 4)
205 swap(pixels[i + 0], pixels[i + 2]);
Ken Russell (switch to Gerrit) 2013/06/27 13:41:02 I'm pretty sure this needs to be conditional depen
206
207 if (m_attributes.alpha && !m_attributes.premultipliedAlpha) {
208 for (int i = 0; i < size().width() * size().height() * 4; i += 4) {
209 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 25 5);
210 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 25 5);
211 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 25 5);
212 }
213 }
214 }
215
190 // We must restore the texture binding since creating new textures, 216 // We must restore the texture binding since creating new textures,
191 // consuming and producing mailboxes changes it. 217 // consuming and producing mailboxes changes it.
192 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); 218 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding);
193 219
194 // First try to recycle an old buffer. 220 // First try to recycle an old buffer.
195 RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox(); 221 RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox();
196 222
197 // No buffer available to recycle, create a new one. 223 // No buffer available to recycle, create a new one.
198 if (!nextFrontColorBuffer) { 224 if (!nextFrontColorBuffer) {
199 unsigned newColorBuffer = createColorTexture(m_size); 225 unsigned newColorBuffer = createColorTexture(m_size);
200 // Bad things happened, abandon ship. 226 // Bad things happened, abandon ship.
201 if (!newColorBuffer) 227 if (!newColorBuffer)
202 return false; 228 return false;
203 229
204 nextFrontColorBuffer = createNewMailbox(newColorBuffer); 230 nextFrontColorBuffer = createNewMailbox(newColorBuffer);
205 } 231 }
206 232
207 if (m_preserveDrawingBuffer == Discard) { 233 if (m_preserveDrawingBuffer == Discard) {
208 m_colorBuffer = nextFrontColorBuffer->textureId; 234 m_colorBuffer = nextFrontColorBuffer->textureId;
209 swap(nextFrontColorBuffer, m_lastColorBuffer); 235 swap(nextFrontColorBuffer, m_lastColorBuffer);
210 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a 236 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a
211 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. 237 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding.
212 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore 238 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore
213 // it after attaching the new back buffer here. 239 // it after attaching the new back buffer here.
214 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); 240 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
215 m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, Graphics Context3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); 241 m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, Graphics Context3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0);
216 } else { 242 } else {
217 Extensions3D* extensions = m_context->getExtensions(); 243 Extensions3D* extensions = m_context->getExtensions();
218 extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBu ffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsConte xt3D::UNSIGNED_BYTE); 244 extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBu ffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsConte xt3D::UNSIGNED_BYTE);
245 SkBitmap nextBitmap = nextFrontColorBuffer->mailbox.bitmap;
246 nextFrontColorBuffer->mailbox.bitmap = m_lastColorBuffer->mailbox.bitmap ;
247 nextFrontColorBuffer->mailbox.size = m_lastColorBuffer->mailbox.size;
248 m_lastColorBuffer->mailbox.bitmap = nextBitmap;
219 } 249 }
220 250
221 if (multisample() && !m_framebufferBinding) 251 if (multisample() && !m_framebufferBinding)
222 bind(); 252 bind();
223 else 253 else
224 restoreFramebufferBinding(); 254 restoreFramebufferBinding();
225 255
226 m_contentsChanged = false; 256 m_contentsChanged = false;
227 257
228 context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer-> textureId); 258 context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer-> textureId);
229 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontCo lorBuffer->mailbox.name); 259 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontCo lorBuffer->mailbox.name);
230 context()->flush(); 260 context()->flush();
231 m_context->markLayerComposited(); 261 m_context->markLayerComposited();
232 262
233 *outMailbox = nextFrontColorBuffer->mailbox; 263 *outMailbox = nextFrontColorBuffer->mailbox;
264
234 m_frontColorBuffer = nextFrontColorBuffer->textureId; 265 m_frontColorBuffer = nextFrontColorBuffer->textureId;
235 return true; 266 return true;
236 } 267 }
237 268
238 void DrawingBuffer::mailboxReleased(const WebKit::WebExternalTextureMailbox& mai lbox) 269 void DrawingBuffer::mailboxReleased(const WebKit::WebExternalTextureMailbox& mai lbox)
239 { 270 {
240 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 271 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
241 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; 272 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
242 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.nam e))) { 273 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name ))) {
243 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; 274 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint;
244 m_recycledMailboxes.append(mailboxInfo.release()); 275 mailboxInfo->mailbox.bitmap = mailbox.bitmap;
245 return; 276 m_recycledMailboxes.append(mailboxInfo.release());
246 } 277 return;
278 }
247 } 279 }
248 ASSERT_NOT_REACHED(); 280 ASSERT_NOT_REACHED();
249 } 281 }
250 282
251 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::getRecycledMailbox() 283 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::getRecycledMailbox()
252 { 284 {
253 if (!m_context || m_recycledMailboxes.isEmpty()) 285 if (!m_context || m_recycledMailboxes.isEmpty())
254 return PassRefPtr<MailboxInfo>(); 286 return PassRefPtr<MailboxInfo>();
255 287
256 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); 288 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release();
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 846
815 void DrawingBuffer::bind() 847 void DrawingBuffer::bind()
816 { 848 {
817 if (!m_context) 849 if (!m_context)
818 return; 850 return;
819 851
820 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); 852 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
821 } 853 }
822 854
823 } // namespace WebCore 855 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698