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

Side by Side Diff: ui/cc/LayerRendererChromium.cpp

Issue 10701016: Initial import attempt, just to play with. Many things disabled/removed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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
« no previous file with comments | « ui/cc/LayerRendererChromium.h ('k') | ui/cc/LayerTextureSubImage.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 #include "config.h"
33
34 #if USE(ACCELERATED_COMPOSITING)
35 #include "LayerRendererChromium.h"
36
37 #include "Extensions3D.h"
38 #include "FloatQuad.h"
39 #include "GeometryBinding.h"
40 #include "GrTexture.h"
41 #include "ManagedTexture.h"
42 #include "NotImplemented.h"
43 #include "PlatformColor.h"
44 //#include "SharedGraphicsContext3D.h"
45 #include "SkBitmap.h"
46 #include "SkColor.h"
47 #include "TextureManager.h"
48 #include "ThrottledTextureUploader.h"
49 #include "TraceEvent.h"
50 #include "TrackingTextureAllocator.h"
51 #include "cc/CCCheckerboardDrawQuad.h"
52 #include "cc/CCDebugBorderDrawQuad.h"
53 #include "cc/CCIOSurfaceDrawQuad.h"
54 #include "cc/CCLayerQuad.h"
55 #include "cc/CCMathUtil.h"
56 #include "cc/CCProxy.h"
57 #include "cc/CCRenderPass.h"
58 #include "cc/CCRenderPassDrawQuad.h"
59 #include "cc/CCRenderSurfaceFilters.h"
60 #include "cc/CCSettings.h"
61 #include "cc/CCSingleThreadProxy.h"
62 #include "cc/CCSolidColorDrawQuad.h"
63 #include "cc/CCStreamVideoDrawQuad.h"
64 #include "cc/CCTextureDrawQuad.h"
65 #include "cc/CCTileDrawQuad.h"
66 #include "cc/CCVideoLayerImpl.h"
67 #include "cc/CCYUVVideoDrawQuad.h"
68 #include <public/WebGraphicsContext3D.h>
69 #include <public/WebVideoFrame.h>
70 #include <wtf/CurrentTime.h>
71 #include <wtf/MainThread.h>
72 #include <wtf/text/StringHash.h>
73
74 using namespace std;
75 using WebKit::WebGraphicsContext3D;
76 using WebKit::WebGraphicsMemoryAllocation;
77 using WebKit::WebTransformationMatrix;
78
79 namespace WebCore {
80
81 namespace {
82
83 static WebTransformationMatrix orthoMatrix(float left, float right, float bottom , float top)
84 {
85 float deltaX = right - left;
86 float deltaY = top - bottom;
87 WebTransformationMatrix ortho;
88 if (!deltaX || !deltaY)
89 return ortho;
90 ortho.setM11(2.0f / deltaX);
91 ortho.setM41(-(right + left) / deltaX);
92 ortho.setM22(2.0f / deltaY);
93 ortho.setM42(-(top + bottom) / deltaY);
94
95 // Z component of vertices is always set to zero as we don't use the depth b uffer
96 // while drawing.
97 ortho.setM33(0);
98
99 return ortho;
100 }
101
102 static WebTransformationMatrix screenMatrix(int x, int y, int width, int height)
103 {
104 WebTransformationMatrix screen;
105
106 // Map to viewport.
107 screen.translate3d(x, y, 0);
108 screen.scale3d(width, height, 0);
109
110 // Map x, y and z to unit square.
111 screen.translate3d(0.5, 0.5, 0.5);
112 screen.scale3d(0.5, 0.5, 0.5);
113
114 return screen;
115 }
116
117 bool needsIOSurfaceReadbackWorkaround()
118 {
119 #if OS(DARWIN)
120 return true;
121 #else
122 return false;
123 #endif
124 }
125
126 class UnthrottledTextureUploader : public TextureUploader {
127 WTF_MAKE_NONCOPYABLE(UnthrottledTextureUploader);
128 public:
129 static PassOwnPtr<UnthrottledTextureUploader> create()
130 {
131 return adoptPtr(new UnthrottledTextureUploader());
132 }
133 virtual ~UnthrottledTextureUploader() { }
134
135 virtual bool isBusy() { return false; }
136 virtual void beginUploads() { }
137 virtual void endUploads() { }
138 virtual void uploadTexture(CCGraphicsContext* context, LayerTextureUpdater:: Texture* texture, TextureAllocator* allocator, const IntRect sourceRect, const I ntRect destRect) { texture->updateRect(context, allocator, sourceRect, destRect) ; }
139
140 protected:
141 UnthrottledTextureUploader() { }
142 };
143
144 } // anonymous namespace
145
146 PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(CCRendererClient * client, WebGraphicsContext3D* context, TextureUploaderOption textureUploaderSe tting)
147 {
148 OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromi um(client, context, textureUploaderSetting)));
149 if (!layerRenderer->initialize())
150 return nullptr;
151
152 return layerRenderer.release();
153 }
154
155 LayerRendererChromium::LayerRendererChromium(CCRendererClient* client,
156 WebGraphicsContext3D* context,
157 TextureUploaderOption textureUpload erSetting)
158 : CCRenderer(client)
159 , m_currentRenderPass(0)
160 , m_currentManagedTexture(0)
161 , m_offscreenFramebufferId(0)
162 , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f))
163 , m_context(context)
164 , m_defaultRenderPass(0)
165 , m_isViewportChanged(false)
166 , m_isFramebufferDiscarded(false)
167 , m_visible(true)
168 , m_textureUploaderSetting(textureUploaderSetting)
169 {
170 ASSERT(m_context);
171 }
172
173 bool LayerRendererChromium::initialize()
174 {
175 if (!m_context->makeContextCurrent())
176 return false;
177
178 m_context->setContextLostCallback(this);
179
180 WebKit::WebString extensionsWebString = m_context->getString(GL_EXTENSIONS);
181 String extensionsString = String(extensionsWebString.data(), extensionsWebSt ring.length());
182 Vector<String> extensionsList;
183 extensionsString.split(' ', extensionsList);
184 HashSet<String> extensions;
185 for (size_t i = 0; i < extensionsList.size(); ++i)
186 extensions.add(extensionsList[i]);
187
188 if (settings().acceleratePainting && extensions.contains("GL_EXT_texture_for mat_BGRA8888")
189 && extensions.contains("GL_EXT_read_format _bgra"))
190 m_capabilities.usingAcceleratedPainting = true;
191 else
192 m_capabilities.usingAcceleratedPainting = false;
193
194
195 m_capabilities.contextHasCachedFrontBuffer = extensions.contains("GL_CHROMIU M_front_buffer_cached");
196
197 m_capabilities.usingPartialSwap = CCSettings::partialSwapEnabled() && extens ions.contains("GL_CHROMIUM_post_sub_buffer");
198
199 m_capabilities.usingMapSub = extensions.contains("GL_CHROMIUM_map_sub");
200
201 // Use the swapBuffers callback only with the threaded proxy.
202 if (CCProxy::hasImplThread())
203 m_capabilities.usingSwapCompleteCallback = extensions.contains("GL_CHROM IUM_swapbuffers_complete_callback");
204 if (m_capabilities.usingSwapCompleteCallback) {
205 m_context->setSwapBuffersCompleteCallbackCHROMIUM(this);
206 }
207
208 m_capabilities.usingSetVisibility = extensions.contains("GL_CHROMIUM_set_vis ibility");
209
210 if (extensions.contains("GL_CHROMIUM_iosurface")) {
211 ASSERT(extensions.contains("GL_ARB_texture_rectangle"));
212 }
213
214 m_capabilities.usingTextureUsageHint = extensions.contains("GL_ANGLE_texture _usage");
215
216 m_capabilities.usingTextureStorageExtension = extensions.contains("GL_EXT_te xture_storage");
217
218 m_capabilities.usingGpuMemoryManager = extensions.contains("GL_CHROMIUM_gpu_ memory_manager");
219 if (m_capabilities.usingGpuMemoryManager)
220 m_context->setMemoryAllocationChangedCallbackCHROMIUM(this);
221 else
222 m_client->setMemoryAllocationLimitBytes(TextureManager::highLimitBytes(v iewportSize()));
223
224 m_capabilities.usingDiscardFramebuffer = extensions.contains("GL_CHROMIUM_di scard_framebuffer");
225
226 m_capabilities.usingEglImage = extensions.contains("GL_OES_EGL_image_externa l");
227
228 GLC(m_context, m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_capabilities.m axTextureSize));
229 m_capabilities.bestTextureFormat = PlatformColor::bestTextureFormat(m_contex t, extensions.contains("GL_EXT_texture_format_BGRA8888"));
230
231 if (!initializeSharedObjects())
232 return false;
233
234 // Make sure the viewport and context gets initialized, even if it is to zer o.
235 viewportChanged();
236 return true;
237 }
238
239 LayerRendererChromium::~LayerRendererChromium()
240 {
241 ASSERT(CCProxy::isImplThread());
242 m_context->setSwapBuffersCompleteCallbackCHROMIUM(0);
243 m_context->setMemoryAllocationChangedCallbackCHROMIUM(0);
244 m_context->setContextLostCallback(0);
245 cleanupSharedObjects();
246 }
247
248 WebGraphicsContext3D* LayerRendererChromium::context()
249 {
250 return m_context;
251 }
252
253 void LayerRendererChromium::debugGLCall(WebGraphicsContext3D* context, const cha r* command, const char* file, int line)
254 {
255 unsigned long error = context->getError();
256 if (error != GL_NO_ERROR)
257 LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
258 }
259
260 void LayerRendererChromium::setVisible(bool visible)
261 {
262 if (m_visible == visible)
263 return;
264 m_visible = visible;
265
266 // TODO: Replace setVisibilityCHROMIUM with an extension to explicitly manag e front/backbuffers
267 // crbug.com/116049
268 if (m_capabilities.usingSetVisibility) {
269 m_context->setVisibilityCHROMIUM(visible);
270 }
271 }
272
273 void LayerRendererChromium::releaseRenderPassTextures()
274 {
275 if (m_implTextureManager)
276 m_implTextureManager->evictAndDeleteAllTextures(m_implTextureAllocator.g et());
277 }
278
279 void LayerRendererChromium::viewportChanged()
280 {
281 m_isViewportChanged = true;
282
283 // Reset the current RenderPass to force an update of the viewport and
284 // projection matrix next time useRenderPass is called.
285 m_currentRenderPass = 0;
286 }
287
288 void LayerRendererChromium::clearRenderPass(const CCRenderPass* renderPass, cons t FloatRect& framebufferDamageRect)
289 {
290 // On DEBUG builds, opaque render passes are cleared to blue to easily see r egions that were not drawn on the screen. If we
291 // are using partial swap / scissor optimization, then the surface should on ly
292 // clear the damaged region, so that we don't accidentally clear un-changed portions
293 // of the screen.
294
295 if (renderPass->hasTransparentBackground())
296 GLC(m_context, m_context->clearColor(0, 0, 0, 0));
297 else
298 GLC(m_context, m_context->clearColor(0, 0, 1, 1));
299
300 if (m_capabilities.usingPartialSwap)
301 setScissorToRect(enclosingIntRect(framebufferDamageRect));
302 else
303 GLC(m_context, m_context->disable(GL_SCISSOR_TEST));
304
305 #if defined(NDEBUG)
306 if (renderPass->hasTransparentBackground())
307 #endif
308 m_context->clear(GL_COLOR_BUFFER_BIT);
309
310 GLC(m_context, m_context->enable(GL_SCISSOR_TEST));
311 }
312
313
314 void LayerRendererChromium::decideRenderPassAllocationsForFrame(const CCRenderPa ssList& renderPassesInDrawOrder)
315 {
316 // FIXME: Get this memory limit from GPU Memory Manager
317 size_t contentsMemoryUseBytes = m_contentsTextureAllocator->currentMemoryUse Bytes();
318 size_t maxLimitBytes = TextureManager::highLimitBytes(viewportSize());
319 size_t memoryLimitBytes = maxLimitBytes - contentsMemoryUseBytes > 0u ? maxL imitBytes - contentsMemoryUseBytes : 0u;
320
321 m_implTextureManager->setMaxMemoryLimitBytes(memoryLimitBytes);
322 }
323
324 void LayerRendererChromium::beginDrawingFrame(const CCRenderPass* rootRenderPass )
325 {
326 // FIXME: Remove this once framebuffer is automatically recreated on first u se
327 ensureFramebuffer();
328
329 m_defaultRenderPass = rootRenderPass;
330 ASSERT(m_defaultRenderPass);
331
332 if (viewportSize().isEmpty())
333 return;
334
335 TRACE_EVENT0("cc", "LayerRendererChromium::drawLayers");
336 if (m_isViewportChanged) {
337 // Only reshape when we know we are going to draw. Otherwise, the reshap e
338 // can leave the window at the wrong size if we never draw and the prope r
339 // viewport size is never set.
340 m_isViewportChanged = false;
341 m_context->reshape(viewportWidth(), viewportHeight());
342 }
343
344 makeContextCurrent();
345 // Bind the common vertex attributes used for drawing all the layers.
346 m_sharedGeometry->prepareForDraw();
347
348 GLC(m_context, m_context->disable(GL_DEPTH_TEST));
349 GLC(m_context, m_context->disable(GL_CULL_FACE));
350 GLC(m_context, m_context->colorMask(true, true, true, true));
351 GLC(m_context, m_context->enable(GL_BLEND));
352 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
353 }
354
355 void LayerRendererChromium::doNoOp()
356 {
357 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0));
358 GLC(m_context, m_context->flush());
359 }
360
361 void LayerRendererChromium::drawRenderPass(const CCRenderPass* renderPass, const FloatRect& framebufferDamageRect)
362 {
363 if (!useRenderPass(renderPass))
364 return;
365
366 clearRenderPass(renderPass, framebufferDamageRect);
367
368 const CCQuadList& quadList = renderPass->quadList();
369 for (CCQuadList::constBackToFrontIterator it = quadList.backToFrontBegin(); it != quadList.backToFrontEnd(); ++it)
370 drawQuad(it->get());
371 }
372
373 void LayerRendererChromium::drawQuad(const CCDrawQuad* quad)
374 {
375 IntRect scissorRect = quad->scissorRect();
376
377 ASSERT(!scissorRect.isEmpty());
378 if (scissorRect.isEmpty())
379 return;
380
381 setScissorToRect(scissorRect);
382
383 if (quad->needsBlending())
384 GLC(m_context, m_context->enable(GL_BLEND));
385 else
386 GLC(m_context, m_context->disable(GL_BLEND));
387
388 switch (quad->material()) {
389 case CCDrawQuad::Invalid:
390 ASSERT_NOT_REACHED();
391 break;
392 case CCDrawQuad::Checkerboard:
393 drawCheckerboardQuad(quad->toCheckerboardDrawQuad());
394 break;
395 case CCDrawQuad::DebugBorder:
396 drawDebugBorderQuad(quad->toDebugBorderDrawQuad());
397 break;
398 case CCDrawQuad::IOSurfaceContent:
399 drawIOSurfaceQuad(quad->toIOSurfaceDrawQuad());
400 break;
401 case CCDrawQuad::RenderPass:
402 drawRenderPassQuad(quad->toRenderPassDrawQuad());
403 break;
404 case CCDrawQuad::SolidColor:
405 drawSolidColorQuad(quad->toSolidColorDrawQuad());
406 break;
407 case CCDrawQuad::StreamVideoContent:
408 drawStreamVideoQuad(quad->toStreamVideoDrawQuad());
409 break;
410 case CCDrawQuad::TextureContent:
411 drawTextureQuad(quad->toTextureDrawQuad());
412 break;
413 case CCDrawQuad::TiledContent:
414 drawTileQuad(quad->toTileDrawQuad());
415 break;
416 case CCDrawQuad::YUVVideoContent:
417 drawYUVVideoQuad(quad->toYUVVideoDrawQuad());
418 break;
419 }
420 }
421
422 void LayerRendererChromium::drawCheckerboardQuad(const CCCheckerboardDrawQuad* q uad)
423 {
424 const TileCheckerboardProgram* program = tileCheckerboardProgram();
425 ASSERT(program && program->initialized());
426 GLC(context(), context()->useProgram(program->program()));
427
428 IntRect tileRect = quad->quadRect();
429 WebTransformationMatrix tileTransform = quad->quadTransform();
430 tileTransform.translate(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0);
431
432 float texOffsetX = tileRect.x();
433 float texOffsetY = tileRect.y();
434 float texScaleX = tileRect.width();
435 float texScaleY = tileRect.height();
436 GLC(context(), context()->uniform4f(program->fragmentShader().texTransformLo cation(), texOffsetX, texOffsetY, texScaleX, texScaleY));
437
438 const int checkerboardWidth = 16;
439 float frequency = 1.0 / checkerboardWidth;
440
441 GLC(context(), context()->uniform1f(program->fragmentShader().frequencyLocat ion(), frequency));
442
443 float opacity = quad->opacity();
444 drawTexturedQuad(tileTransform,
445 tileRect.width(), tileRect.height(), opacity, FloatQuad(),
446 program->vertexShader().matrixLocation(),
447 program->fragmentShader().alphaLocation(), -1);
448 }
449
450 void LayerRendererChromium::drawDebugBorderQuad(const CCDebugBorderDrawQuad* qua d)
451 {
452 static float glMatrix[16];
453 const SolidColorProgram* program = solidColorProgram();
454 ASSERT(program && program->initialized());
455 GLC(context(), context()->useProgram(program->program()));
456
457 const IntRect& layerRect = quad->quadRect();
458 WebTransformationMatrix renderMatrix = quad->quadTransform();
459 renderMatrix.translate(0.5 * layerRect.width() + layerRect.x(), 0.5 * layerR ect.height() + layerRect.y());
460 renderMatrix.scaleNonUniform(layerRect.width(), layerRect.height());
461 LayerRendererChromium::toGLMatrix(&glMatrix[0], projectionMatrix() * renderM atrix);
462 GLC(context(), context()->uniformMatrix4fv(program->vertexShader().matrixLoc ation(), 1, false, &glMatrix[0]));
463
464 SkColor color = quad->color();
465 float alpha = SkColorGetA(color) / 255.0;
466
467 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha));
468
469 GLC(context(), context()->lineWidth(quad->width()));
470
471 // The indices for the line are stored in the same array as the triangle ind ices.
472 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
473 }
474
475 static inline SkBitmap applyFilters(LayerRendererChromium* layerRenderer, const WebKit::WebFilterOperations& filters, ManagedTexture* sourceTexture)
476 {
477 if (filters.isEmpty())
478 return SkBitmap();
479
480 return SkBitmap();
481 /*
482 RefPtr<GraphicsContext3D> filterContext = CCProxy::hasImplThread() ? SharedG raphicsContext3D::getForImplThread() : SharedGraphicsContext3D::get();
483 if (!filterContext)
484 return SkBitmap();
485
486 layerRenderer->context()->flush();
487
488 return CCRenderSurfaceFilters::apply(filters, sourceTexture->textureId(), so urceTexture->size(), filterContext.get());
489 */
490 }
491
492 void LayerRendererChromium::drawBackgroundFilters(const CCRenderPassDrawQuad* qu ad, const WebTransformationMatrix& contentsDeviceTransform)
493 {
494 // This method draws a background filter, which applies a filter to any pixe ls behind the quad and seen through its background.
495 // The algorithm works as follows:
496 // 1. Compute a bounding box around the pixels that will be visible through the quad.
497 // 2. Read the pixels in the bounding box into a buffer R.
498 // 3. Apply the background filter to R, so that it is applied in the pixels' coordinate space.
499 // 4. Apply the quad's inverse transform to map the pixels in R into the qua d's content space. This implicitly
500 // clips R by the content bounds of the quad since the destination texture h as bounds matching the quad's content.
501 // 5. Draw the background texture for the contents using the same transform as used to draw the contents itself. This is done
502 // without blending to replace the current background pixels with the new fi ltered background.
503 // 6. Draw the contents of the quad over drop of the new background with ble nding, as per usual. The filtered background
504 // pixels will show through any non-opaque pixels in this draws.
505 //
506 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
507
508 CCRenderSurface* drawingSurface = quad->renderPass()->targetSurface();
509 if (quad->backgroundFilters().isEmpty())
510 return;
511
512 // FIXME: We only allow background filters on an opaque render surface becau se other surfaces may contain
513 // translucent pixels, and the contents behind those translucent pixels woul dn't have the filter applied.
514 if (m_currentRenderPass->hasTransparentBackground())
515 return;
516 ASSERT(!m_currentManagedTexture);
517
518 // FIXME: Do a single readback for both the surface and replica and cache th e filtered results (once filter textures are not reused).
519 IntRect deviceRect = enclosingIntRect(CCMathUtil::mapClippedRect(contentsDev iceTransform, sharedGeometryQuad().boundingBox()));
520
521 int top, right, bottom, left;
522 quad->backgroundFilters().getOutsets(top, right, bottom, left);
523 deviceRect.move(-left, -top);
524 deviceRect.expand(left + right, top + bottom);
525
526 deviceRect.intersect(m_currentRenderPass->framebufferOutputRect());
527
528 OwnPtr<ManagedTexture> deviceBackgroundTexture = ManagedTexture::create(m_im plTextureManager.get());
529 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect))
530 return;
531
532 SkBitmap filteredDeviceBackground = applyFilters(this, quad->backgroundFilte rs(), deviceBackgroundTexture.get());
533 if (!filteredDeviceBackground.getTexture())
534 return;
535
536 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g etTexture());
537 int filteredDeviceBackgroundTextureId = texture->getTextureHandle();
538
539 if (!drawingSurface->prepareBackgroundTexture(this))
540 return;
541
542 const CCRenderPass* targetRenderPass = m_currentRenderPass;
543 if (useManagedTexture(drawingSurface->backgroundTexture(), quad->quadRect()) ) {
544 // Copy the readback pixels from device to the background texture for th e surface.
545 WebTransformationMatrix deviceToFramebufferTransform;
546 deviceToFramebufferTransform.translate(quad->quadRect().width() / 2.0, q uad->quadRect().height() / 2.0);
547 deviceToFramebufferTransform.scale3d(quad->quadRect().width(), quad->qua dRect().height(), 1);
548 deviceToFramebufferTransform.multiply(contentsDeviceTransform.inverse()) ;
549 deviceToFramebufferTransform.translate(deviceRect.width() / 2.0, deviceR ect.height() / 2.0);
550 deviceToFramebufferTransform.translate(deviceRect.x(), deviceRect.y());
551
552 copyTextureToFramebuffer(filteredDeviceBackgroundTextureId, deviceRect.s ize(), deviceToFramebufferTransform);
553
554 useRenderPass(targetRenderPass);
555 }
556 }
557
558 void LayerRendererChromium::drawRenderPassQuad(const CCRenderPassDrawQuad* quad)
559 {
560 // The replica is always drawn first, so free after drawing the contents.
561 bool shouldReleaseTextures = !quad->isReplica();
562
563 CCRenderSurface* drawingSurface = quad->renderPass()->targetSurface();
564
565 WebTransformationMatrix renderTransform = quad->layerTransform();
566 // Apply a scaling factor to size the quad from 1x1 to its intended size.
567 renderTransform.scale3d(quad->quadRect().width(), quad->quadRect().height(), 1);
568 WebTransformationMatrix contentsDeviceTransform = WebTransformationMatrix(wi ndowMatrix() * projectionMatrix() * renderTransform).to2dTransform();
569
570 // Can only draw surface if device matrix is invertible.
571 if (!contentsDeviceTransform.isInvertible() || !drawingSurface->hasValidCont entsTexture()) {
572 if (shouldReleaseTextures) {
573 drawingSurface->releaseBackgroundTexture();
574 drawingSurface->releaseContentsTexture();
575 }
576 return;
577 }
578
579 drawBackgroundFilters(quad, contentsDeviceTransform);
580
581 // FIXME: Cache this value so that we don't have to do it for both the surfa ce and its replica.
582 // Apply filters to the contents texture.
583 SkBitmap filterBitmap = applyFilters(this, quad->filters(), drawingSurface-> contentsTexture());
584 int contentsTextureId = drawingSurface->contentsTexture()->textureId();
585 if (filterBitmap.getTexture()) {
586 GrTexture* texture = reinterpret_cast<GrTexture*>(filterBitmap.getTextur e());
587 contentsTextureId = texture->getTextureHandle();
588 }
589
590 // Draw the background texture if there is one.
591 if (drawingSurface->hasValidBackgroundTexture())
592 copyTextureToFramebuffer(drawingSurface->backgroundTexture()->textureId( ), quad->quadRect().size(), quad->layerTransform());
593
594 FloatQuad deviceQuad = contentsDeviceTransform.mapQuad(sharedGeometryQuad()) ;
595 CCLayerQuad deviceLayerBounds = CCLayerQuad(FloatQuad(deviceQuad.boundingBox ()));
596 CCLayerQuad deviceLayerEdges = CCLayerQuad(deviceQuad);
597
598 // Use anti-aliasing programs only when necessary.
599 bool useAA = (!deviceQuad.isRectilinear() || !deviceQuad.boundingBox().isExp ressibleAsIntRect());
600 if (useAA) {
601 deviceLayerBounds.inflateAntiAliasingDistance();
602 deviceLayerEdges.inflateAntiAliasingDistance();
603 }
604
605 bool useMask = quad->maskTextureId();
606
607 // FIXME: use the backgroundTexture and blend the background in with this dr aw instead of having a separate copy of the background texture.
608
609 GLC(context(), context()->activeTexture(GL_TEXTURE0));
610 context()->bindTexture(GL_TEXTURE_2D, contentsTextureId);
611
612 int shaderQuadLocation = -1;
613 int shaderEdgeLocation = -1;
614 int shaderMaskSamplerLocation = -1;
615 int shaderMatrixLocation = -1;
616 int shaderAlphaLocation = -1;
617 if (useAA && useMask) {
618 const RenderPassMaskProgramAA* program = renderPassMaskProgramAA();
619 GLC(context(), context()->useProgram(program->program()));
620 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLoc ation(), 0));
621
622 shaderQuadLocation = program->vertexShader().pointLocation();
623 shaderEdgeLocation = program->fragmentShader().edgeLocation();
624 shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocatio n();
625 shaderMatrixLocation = program->vertexShader().matrixLocation();
626 shaderAlphaLocation = program->fragmentShader().alphaLocation();
627 } else if (!useAA && useMask) {
628 const RenderPassMaskProgram* program = renderPassMaskProgram();
629 GLC(context(), context()->useProgram(program->program()));
630 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLoc ation(), 0));
631
632 shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocatio n();
633 shaderMatrixLocation = program->vertexShader().matrixLocation();
634 shaderAlphaLocation = program->fragmentShader().alphaLocation();
635 } else if (useAA && !useMask) {
636 const RenderPassProgramAA* program = renderPassProgramAA();
637 GLC(context(), context()->useProgram(program->program()));
638 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLoc ation(), 0));
639
640 shaderQuadLocation = program->vertexShader().pointLocation();
641 shaderEdgeLocation = program->fragmentShader().edgeLocation();
642 shaderMatrixLocation = program->vertexShader().matrixLocation();
643 shaderAlphaLocation = program->fragmentShader().alphaLocation();
644 } else {
645 const RenderPassProgram* program = renderPassProgram();
646 GLC(context(), context()->useProgram(program->program()));
647 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLoc ation(), 0));
648
649 shaderMatrixLocation = program->vertexShader().matrixLocation();
650 shaderAlphaLocation = program->fragmentShader().alphaLocation();
651 }
652
653 if (shaderMaskSamplerLocation != -1) {
654 GLC(context(), context()->activeTexture(GL_TEXTURE1));
655 GLC(context(), context()->uniform1i(shaderMaskSamplerLocation, 1));
656 context()->bindTexture(GL_TEXTURE_2D, quad->maskTextureId());
657 GLC(context(), context()->activeTexture(GL_TEXTURE0));
658 }
659
660 if (shaderEdgeLocation != -1) {
661 float edge[24];
662 deviceLayerEdges.toFloatArray(edge);
663 deviceLayerBounds.toFloatArray(&edge[12]);
664 GLC(context(), context()->uniform3fv(shaderEdgeLocation, 8, edge));
665 }
666
667 // Map device space quad to surface space.
668 FloatQuad surfaceQuad = contentsDeviceTransform.inverse().mapQuad(deviceLaye rEdges.floatQuad());
669
670 drawTexturedQuad(quad->layerTransform(), quad->quadRect().width(), quad->qua dRect().height(), quad->opacity(), surfaceQuad,
671 shaderMatrixLocation, shaderAlphaLocation, shaderQuadLocati on);
672
673 if (shouldReleaseTextures) {
674 drawingSurface->releaseBackgroundTexture();
675 drawingSurface->releaseContentsTexture();
676 }
677 }
678
679 void LayerRendererChromium::drawSolidColorQuad(const CCSolidColorDrawQuad* quad)
680 {
681 const SolidColorProgram* program = solidColorProgram();
682 GLC(context(), context()->useProgram(program->program()));
683
684 IntRect tileRect = quad->quadRect();
685
686 WebTransformationMatrix tileTransform = quad->quadTransform();
687 tileTransform.translate(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0);
688
689 SkColor color = quad->color();
690 float opacity = quad->opacity();
691 float alpha = (SkColorGetA(color) / 255.0) * opacity;
692
693 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha));
694
695 drawTexturedQuad(tileTransform,
696 tileRect.width(), tileRect.height(), 1.0, FloatQuad(),
697 program->vertexShader().matrixLocation(),
698 -1, -1);
699 }
700
701 struct TileProgramUniforms {
702 unsigned program;
703 unsigned samplerLocation;
704 unsigned vertexTexTransformLocation;
705 unsigned fragmentTexTransformLocation;
706 unsigned edgeLocation;
707 unsigned matrixLocation;
708 unsigned alphaLocation;
709 unsigned pointLocation;
710 };
711
712 template<class T>
713 static void tileUniformLocation(T program, TileProgramUniforms& uniforms)
714 {
715 uniforms.program = program->program();
716 uniforms.vertexTexTransformLocation = program->vertexShader().vertexTexTrans formLocation();
717 uniforms.matrixLocation = program->vertexShader().matrixLocation();
718 uniforms.pointLocation = program->vertexShader().pointLocation();
719
720 uniforms.samplerLocation = program->fragmentShader().samplerLocation();
721 uniforms.alphaLocation = program->fragmentShader().alphaLocation();
722 uniforms.fragmentTexTransformLocation = program->fragmentShader().fragmentTe xTransformLocation();
723 uniforms.edgeLocation = program->fragmentShader().edgeLocation();
724 }
725
726 void LayerRendererChromium::drawTileQuad(const CCTileDrawQuad* quad)
727 {
728 const IntRect& tileRect = quad->quadVisibleRect();
729
730 FloatRect clampRect(tileRect);
731 // Clamp texture coordinates to avoid sampling outside the layer
732 // by deflating the tile region half a texel or half a texel
733 // minus epsilon for one pixel layers. The resulting clamp region
734 // is mapped to the unit square by the vertex shader and mapped
735 // back to normalized texture coordinates by the fragment shader
736 // after being clamped to 0-1 range.
737 const float epsilon = 1 / 1024.0f;
738 float clampX = min(0.5, clampRect.width() / 2.0 - epsilon);
739 float clampY = min(0.5, clampRect.height() / 2.0 - epsilon);
740 clampRect.inflateX(-clampX);
741 clampRect.inflateY(-clampY);
742 FloatSize clampOffset = clampRect.minXMinYCorner() - FloatRect(tileRect).min XMinYCorner();
743
744 FloatPoint textureOffset = quad->textureOffset() + clampOffset +
745 IntPoint(quad->quadVisibleRect().location() - qua d->quadRect().location());
746
747 // Map clamping rectangle to unit square.
748 float vertexTexTranslateX = -clampRect.x() / clampRect.width();
749 float vertexTexTranslateY = -clampRect.y() / clampRect.height();
750 float vertexTexScaleX = tileRect.width() / clampRect.width();
751 float vertexTexScaleY = tileRect.height() / clampRect.height();
752
753 // Map to normalized texture coordinates.
754 const IntSize& textureSize = quad->textureSize();
755 float fragmentTexTranslateX = textureOffset.x() / textureSize.width();
756 float fragmentTexTranslateY = textureOffset.y() / textureSize.height();
757 float fragmentTexScaleX = clampRect.width() / textureSize.width();
758 float fragmentTexScaleY = clampRect.height() / textureSize.height();
759
760
761 FloatQuad localQuad;
762 WebTransformationMatrix deviceTransform = WebTransformationMatrix(windowMatr ix() * projectionMatrix() * quad->quadTransform()).to2dTransform();
763 if (!deviceTransform.isInvertible())
764 return;
765
766 bool clipped = false;
767 FloatQuad deviceLayerQuad = CCMathUtil::mapQuad(deviceTransform, FloatQuad(q uad->layerRect()), clipped);
768
769 TileProgramUniforms uniforms;
770 // For now, we simply skip anti-aliasing with the quad is clipped. This only happens
771 // on perspective transformed layers that go partially behind the camera.
772 if (quad->isAntialiased() && !clipped) {
773 if (quad->swizzleContents())
774 tileUniformLocation(tileProgramSwizzleAA(), uniforms);
775 else
776 tileUniformLocation(tileProgramAA(), uniforms);
777 } else {
778 if (quad->needsBlending()) {
779 if (quad->swizzleContents())
780 tileUniformLocation(tileProgramSwizzle(), uniforms);
781 else
782 tileUniformLocation(tileProgram(), uniforms);
783 } else {
784 if (quad->swizzleContents())
785 tileUniformLocation(tileProgramSwizzleOpaque(), uniforms);
786 else
787 tileUniformLocation(tileProgramOpaque(), uniforms);
788 }
789 }
790
791 GLC(context(), context()->useProgram(uniforms.program));
792 GLC(context(), context()->uniform1i(uniforms.samplerLocation, 0));
793 GLC(context(), context()->activeTexture(GL_TEXTURE0));
794 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, quad->textureId()));
795 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , quad->textureFilter()));
796 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , quad->textureFilter()));
797
798
799 if (!clipped && quad->isAntialiased()) {
800
801 CCLayerQuad deviceLayerBounds = CCLayerQuad(FloatQuad(deviceLayerQuad.bo undingBox()));
802 deviceLayerBounds.inflateAntiAliasingDistance();
803
804 CCLayerQuad deviceLayerEdges = CCLayerQuad(deviceLayerQuad);
805 deviceLayerEdges.inflateAntiAliasingDistance();
806
807 float edge[24];
808 deviceLayerEdges.toFloatArray(edge);
809 deviceLayerBounds.toFloatArray(&edge[12]);
810 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge));
811
812 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY));
813 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS caleY));
814
815 FloatPoint bottomRight(tileRect.maxX(), tileRect.maxY());
816 FloatPoint bottomLeft(tileRect.x(), tileRect.maxY());
817 FloatPoint topLeft(tileRect.x(), tileRect.y());
818 FloatPoint topRight(tileRect.maxX(), tileRect.y());
819
820 // Map points to device space.
821 bottomRight = deviceTransform.mapPoint(bottomRight);
822 bottomLeft = deviceTransform.mapPoint(bottomLeft);
823 topLeft = deviceTransform.mapPoint(topLeft);
824 topRight = deviceTransform.mapPoint(topRight);
825
826 CCLayerQuad::Edge bottomEdge(bottomRight, bottomLeft);
827 CCLayerQuad::Edge leftEdge(bottomLeft, topLeft);
828 CCLayerQuad::Edge topEdge(topLeft, topRight);
829 CCLayerQuad::Edge rightEdge(topRight, bottomRight);
830
831 // Only apply anti-aliasing to edges not clipped during culling.
832 if (quad->topEdgeAA() && tileRect.y() == quad->quadRect().y())
833 topEdge = deviceLayerEdges.top();
834 if (quad->leftEdgeAA() && tileRect.x() == quad->quadRect().x())
835 leftEdge = deviceLayerEdges.left();
836 if (quad->rightEdgeAA() && tileRect.maxX() == quad->quadRect().maxX())
837 rightEdge = deviceLayerEdges.right();
838 if (quad->bottomEdgeAA() && tileRect.maxY() == quad->quadRect().maxY())
839 bottomEdge = deviceLayerEdges.bottom();
840
841 float sign = FloatQuad(tileRect).isCounterclockwise() ? -1 : 1;
842 bottomEdge.scale(sign);
843 leftEdge.scale(sign);
844 topEdge.scale(sign);
845 rightEdge.scale(sign);
846
847 // Create device space quad.
848 CCLayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge);
849
850 // Map quad to layer space.
851 WebTransformationMatrix inverseDeviceTransform = deviceTransform.inverse ();
852 localQuad = inverseDeviceTransform.mapQuad(deviceQuad.floatQuad());
853 } else {
854 // Move fragment shader transform to vertex shader. We can do this while
855 // still producing correct results as fragmentTexTransformLocation
856 // should always be non-negative when tiles are transformed in a way
857 // that could result in sampling outside the layer.
858 vertexTexScaleX *= fragmentTexScaleX;
859 vertexTexScaleY *= fragmentTexScaleY;
860 vertexTexTranslateX *= fragmentTexScaleX;
861 vertexTexTranslateY *= fragmentTexScaleY;
862 vertexTexTranslateX += fragmentTexTranslateX;
863 vertexTexTranslateY += fragmentTexTranslateY;
864
865 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY));
866
867 localQuad = FloatRect(tileRect);
868 }
869
870 // Normalize to tileRect.
871 localQuad.scale(1.0f / tileRect.width(), 1.0f / tileRect.height());
872
873 drawTexturedQuad(quad->quadTransform(), tileRect.width(), tileRect.height(), quad->opacity(), localQuad, uniforms.matrixLocation, uniforms.alphaLocation, un iforms.pointLocation);
874 }
875
876 void LayerRendererChromium::drawYUVVideoQuad(const CCYUVVideoDrawQuad* quad)
877 {
878 const VideoYUVProgram* program = videoYUVProgram();
879 ASSERT(program && program->initialized());
880
881 const CCVideoLayerImpl::FramePlane& yPlane = quad->yPlane();
882 const CCVideoLayerImpl::FramePlane& uPlane = quad->uPlane();
883 const CCVideoLayerImpl::FramePlane& vPlane = quad->vPlane();
884
885 GLC(context(), context()->activeTexture(GL_TEXTURE1));
886 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, yPlane.textureId));
887 GLC(context(), context()->activeTexture(GL_TEXTURE2));
888 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, uPlane.textureId));
889 GLC(context(), context()->activeTexture(GL_TEXTURE3));
890 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, vPlane.textureId));
891
892 GLC(context(), context()->useProgram(program->program()));
893
894 float yWidthScaleFactor = static_cast<float>(yPlane.visibleSize.width()) / y Plane.size.width();
895 // Arbitrarily take the u sizes because u and v dimensions are identical.
896 float uvWidthScaleFactor = static_cast<float>(uPlane.visibleSize.width()) / uPlane.size.width();
897 GLC(context(), context()->uniform1f(program->vertexShader().yWidthScaleFacto rLocation(), yWidthScaleFactor));
898 GLC(context(), context()->uniform1f(program->vertexShader().uvWidthScaleFact orLocation(), uvWidthScaleFactor));
899
900 GLC(context(), context()->uniform1i(program->fragmentShader().yTextureLocati on(), 1));
901 GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocati on(), 2));
902 GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocati on(), 3));
903
904 // These values are magic numbers that are used in the transformation from Y UV to RGB color values.
905 // They are taken from the following webpage: http://www.fourcc.org/fccyvrgb .php
906 float yuv2RGB[9] = {
907 1.164f, 1.164f, 1.164f,
908 0.f, -.391f, 2.018f,
909 1.596f, -.813f, 0.f,
910 };
911 GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().ccMatri xLocation(), 1, 0, yuv2RGB));
912
913 // These values map to 16, 128, and 128 respectively, and are computed
914 // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
915 // They are used in the YUV to RGBA conversion formula:
916 // Y - 16 : Gives 16 values of head and footroom for overshooting
917 // U - 128 : Turns unsigned U into signed U [-128,127]
918 // V - 128 : Turns unsigned V into signed V [-128,127]
919 float yuvAdjust[3] = {
920 -0.0625f,
921 -0.5f,
922 -0.5f,
923 };
924 GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocatio n(), 1, yuvAdjust));
925
926 const IntSize& bounds = quad->quadRect().size();
927 drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), qu ad->opacity(), FloatQuad(),
928 program->vertexShader().matrixLocation(),
929 program->fragmentShader().alphaLocation(),
930 -1);
931
932 // Reset active texture back to texture 0.
933 GLC(context(), context()->activeTexture(GL_TEXTURE0));
934 }
935
936 void LayerRendererChromium::drawStreamVideoQuad(const CCStreamVideoDrawQuad* qua d)
937 {
938 static float glMatrix[16];
939
940 ASSERT(m_capabilities.usingEglImage);
941
942 const VideoStreamTextureProgram* program = videoStreamTextureProgram();
943 GLC(context(), context()->useProgram(program->program()));
944
945 toGLMatrix(&glMatrix[0], quad->matrix());
946 GLC(context(), context()->uniformMatrix4fv(program->vertexShader().texMatrix Location(), 1, false, glMatrix));
947
948 GLC(context(), context()->activeTexture(GL_TEXTURE0));
949 GLC(context(), context()->bindTexture(GL_TEXTURE_EXTERNAL_OES, quad->texture Id()));
950
951 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocatio n(), 0));
952
953 const IntSize& bounds = quad->quadRect().size();
954 drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), qu ad->opacity(), sharedGeometryQuad(),
955 program->vertexShader().matrixLocation(),
956 program->fragmentShader().alphaLocation(),
957 -1);
958 }
959
960 struct TextureProgramBinding {
961 template<class Program> void set(Program* program)
962 {
963 ASSERT(program && program->initialized());
964 programId = program->program();
965 samplerLocation = program->fragmentShader().samplerLocation();
966 matrixLocation = program->vertexShader().matrixLocation();
967 alphaLocation = program->fragmentShader().alphaLocation();
968 }
969 int programId;
970 int samplerLocation;
971 int matrixLocation;
972 int alphaLocation;
973 };
974
975 struct TexTransformTextureProgramBinding : TextureProgramBinding {
976 template<class Program> void set(Program* program)
977 {
978 TextureProgramBinding::set(program);
979 texTransformLocation = program->vertexShader().texTransformLocation();
980 }
981 int texTransformLocation;
982 };
983
984 void LayerRendererChromium::drawTextureQuad(const CCTextureDrawQuad* quad)
985 {
986 ASSERT(CCProxy::isImplThread());
987
988 TexTransformTextureProgramBinding binding;
989 if (quad->flipped())
990 binding.set(textureProgramFlip());
991 else
992 binding.set(textureProgram());
993 GLC(context(), context()->useProgram(binding.programId));
994 GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
995 const FloatRect& uvRect = quad->uvRect();
996 GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x() , uvRect.y(), uvRect.width(), uvRect.height()));
997
998 GLC(context(), context()->activeTexture(GL_TEXTURE0));
999 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, quad->textureId()));
1000
1001 // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
1002 // where it will only happen once per texture.
1003 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR));
1004 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR));
1005 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL _CLAMP_TO_EDGE));
1006 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL _CLAMP_TO_EDGE));
1007
1008 if (!quad->premultipliedAlpha())
1009 GLC(context(), context()->blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ));
1010
1011 WebTransformationMatrix quadTransform = quad->quadTransform();
1012 IntRect quadRect = quad->quadRect();
1013 quadTransform.translate(quadRect.x() + quadRect.width() / 2.0, quadRect.y() + quadRect.height() / 2.0);
1014
1015 drawTexturedQuad(quadTransform, quadRect.width(), quadRect.height(), quad->o pacity(), sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocation, - 1);
1016
1017 if (!quad->premultipliedAlpha())
1018 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
1019 }
1020
1021 void LayerRendererChromium::drawIOSurfaceQuad(const CCIOSurfaceDrawQuad* quad)
1022 {
1023 ASSERT(CCProxy::isImplThread());
1024 TexTransformTextureProgramBinding binding;
1025 binding.set(textureIOSurfaceProgram());
1026
1027 GLC(context(), context()->useProgram(binding.programId));
1028 GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
1029 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0, quad ->ioSurfaceSize().width(), quad->ioSurfaceSize().height()));
1030
1031 GLC(context(), context()->activeTexture(GL_TEXTURE0));
1032 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, quad->ioSurf aceTextureId()));
1033
1034 // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
1035 // where it will only happen once per texture.
1036 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR));
1037 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR));
1038 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL _CLAMP_TO_EDGE));
1039 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL _CLAMP_TO_EDGE));
1040
1041 const IntSize& bounds = quad->quadRect().size();
1042
1043 drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), qu ad->opacity(), sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocati on, -1);
1044
1045 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, 0));
1046 }
1047
1048 void LayerRendererChromium::drawHeadsUpDisplay(ManagedTexture* hudTexture, const IntSize& hudSize)
1049 {
1050 GLC(m_context, m_context->enable(GL_BLEND));
1051 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
1052 GLC(m_context, m_context->disable(GL_SCISSOR_TEST));
1053 useRenderPass(m_defaultRenderPass);
1054
1055 const HeadsUpDisplayProgram* program = headsUpDisplayProgram();
1056 ASSERT(program && program->initialized());
1057 GLC(m_context, m_context->activeTexture(GL_TEXTURE0));
1058 if (!hudTexture->textureId())
1059 hudTexture->allocate(m_implTextureAllocator.get());
1060 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, hudTexture->textureId() ));
1061 GLC(m_context, m_context->useProgram(program->program()));
1062 GLC(m_context, m_context->uniform1i(program->fragmentShader().samplerLocatio n(), 0));
1063
1064 WebTransformationMatrix matrix;
1065 matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0);
1066 drawTexturedQuad(matrix, hudSize.width(), hudSize.height(),
1067 1, sharedGeometryQuad(), program->vertexShader().matrixLoca tion(),
1068 program->fragmentShader().alphaLocation(),
1069 -1);
1070 }
1071
1072 void LayerRendererChromium::finishDrawingFrame()
1073 {
1074 GLC(m_context, m_context->disable(GL_SCISSOR_TEST));
1075 GLC(m_context, m_context->disable(GL_BLEND));
1076
1077 m_implTextureManager->unprotectAllTextures();
1078 m_implTextureManager->deleteEvictedTextures(m_implTextureAllocator.get());
1079 }
1080
1081 void LayerRendererChromium::toGLMatrix(float* flattened, const WebTransformation Matrix& m)
1082 {
1083 flattened[0] = m.m11();
1084 flattened[1] = m.m12();
1085 flattened[2] = m.m13();
1086 flattened[3] = m.m14();
1087 flattened[4] = m.m21();
1088 flattened[5] = m.m22();
1089 flattened[6] = m.m23();
1090 flattened[7] = m.m24();
1091 flattened[8] = m.m31();
1092 flattened[9] = m.m32();
1093 flattened[10] = m.m33();
1094 flattened[11] = m.m34();
1095 flattened[12] = m.m41();
1096 flattened[13] = m.m42();
1097 flattened[14] = m.m43();
1098 flattened[15] = m.m44();
1099 }
1100
1101 void LayerRendererChromium::drawTexturedQuad(const WebTransformationMatrix& draw Matrix,
1102 float width, float height, float op acity, const FloatQuad& quad,
1103 int matrixLocation, int alphaLocati on, int quadLocation)
1104 {
1105 static float glMatrix[16];
1106
1107 WebTransformationMatrix renderMatrix = drawMatrix;
1108
1109 // Apply a scaling factor to size the quad from 1x1 to its intended size.
1110 renderMatrix.scale3d(width, height, 1);
1111
1112 // Apply the projection matrix before sending the transform over to the shad er.
1113 toGLMatrix(&glMatrix[0], m_projectionMatrix * renderMatrix);
1114
1115 GLC(m_context, m_context->uniformMatrix4fv(matrixLocation, 1, false, &glMatr ix[0]));
1116
1117 if (quadLocation != -1) {
1118 float point[8];
1119 point[0] = quad.p1().x();
1120 point[1] = quad.p1().y();
1121 point[2] = quad.p2().x();
1122 point[3] = quad.p2().y();
1123 point[4] = quad.p3().x();
1124 point[5] = quad.p3().y();
1125 point[6] = quad.p4().x();
1126 point[7] = quad.p4().y();
1127 GLC(m_context, m_context->uniform2fv(quadLocation, 4, point));
1128 }
1129
1130 if (alphaLocation != -1)
1131 GLC(m_context, m_context->uniform1f(alphaLocation, opacity));
1132
1133 GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 ));
1134 }
1135
1136 void LayerRendererChromium::copyTextureToFramebuffer(int textureId, const IntSiz e& bounds, const WebTransformationMatrix& drawMatrix)
1137 {
1138 const RenderPassProgram* program = renderPassProgram();
1139
1140 GLC(context(), context()->activeTexture(GL_TEXTURE0));
1141 GLC(context(), context()->bindTexture(GL_TEXTURE_2D, textureId));
1142 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR));
1143 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR));
1144 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL _CLAMP_TO_EDGE));
1145 GLC(context(), context()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL _CLAMP_TO_EDGE));
1146
1147 GLC(context(), context()->useProgram(program->program()));
1148 GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocatio n(), 0));
1149 drawTexturedQuad(drawMatrix, bounds.width(), bounds.height(), 1, sharedGeome tryQuad(),
1150 program->vertexShader().matrixLocation(),
1151 program->fragmentShader().alphaLocation(),
1152 -1);
1153 }
1154
1155 void LayerRendererChromium::finish()
1156 {
1157 TRACE_EVENT0("cc", "LayerRendererChromium::finish");
1158 m_context->finish();
1159 }
1160
1161 bool LayerRendererChromium::swapBuffers(const IntRect& subBuffer)
1162 {
1163 ASSERT(m_visible);
1164 ASSERT(!m_isFramebufferDiscarded);
1165
1166 TRACE_EVENT0("cc", "LayerRendererChromium::swapBuffers");
1167 // We're done! Time to swapbuffers!
1168
1169 if (m_capabilities.usingPartialSwap) {
1170 // If supported, we can save significant bandwidth by only swapping the damaged/scissored region (clamped to the viewport)
1171 IntRect clippedSubBuffer = subBuffer;
1172 clippedSubBuffer.intersect(IntRect(IntPoint::zero(), viewportSize()));
1173 int flippedYPosOfRectBottom = viewportHeight() - clippedSubBuffer.y() - clippedSubBuffer.height();
1174 m_context->postSubBufferCHROMIUM(clippedSubBuffer.x(), flippedYPosOfRect Bottom, clippedSubBuffer.width(), clippedSubBuffer.height());
1175 } else
1176 // Note that currently this has the same effect as swapBuffers; we shoul d
1177 // consider exposing a different entry point on WebGraphicsContext3D.
1178 m_context->prepareTexture();
1179
1180 return true;
1181 }
1182
1183 void LayerRendererChromium::onSwapBuffersComplete()
1184 {
1185 m_client->onSwapBuffersComplete();
1186 }
1187
1188 void LayerRendererChromium::onMemoryAllocationChanged(WebGraphicsMemoryAllocatio n allocation)
1189 {
1190 // FIXME: This is called on the main thread in single threaded mode, but we expect it on the impl thread.
1191 if (!CCProxy::hasImplThread()) {
1192 ASSERT(CCProxy::isMainThread());
1193 DebugScopedSetImplThread impl;
1194 onMemoryAllocationChangedOnImplThread(allocation);
1195 } else {
1196 ASSERT(CCProxy::isImplThread());
1197 onMemoryAllocationChangedOnImplThread(allocation);
1198 }
1199 }
1200
1201 void LayerRendererChromium::onMemoryAllocationChangedOnImplThread(WebKit::WebGra phicsMemoryAllocation allocation)
1202 {
1203 if (m_visible && !allocation.gpuResourceSizeInBytes)
1204 return;
1205
1206 if (!allocation.suggestHaveBackbuffer && !m_visible)
1207 discardFramebuffer();
1208
1209 if (!allocation.gpuResourceSizeInBytes) {
1210 releaseRenderPassTextures();
1211 m_client->releaseContentsTextures();
1212 GLC(m_context, m_context->flush());
1213 } else
1214 m_client->setMemoryAllocationLimitBytes(allocation.gpuResourceSizeInByte s);
1215 }
1216
1217 void LayerRendererChromium::discardFramebuffer()
1218 {
1219 if (m_isFramebufferDiscarded)
1220 return;
1221
1222 if (!m_capabilities.usingDiscardFramebuffer)
1223 return;
1224
1225 // FIXME: Update attachments argument to appropriate values once they are no longer ignored.
1226 m_context->discardFramebufferEXT(GL_TEXTURE_2D, 0, 0);
1227 m_isFramebufferDiscarded = true;
1228
1229 // Damage tracker needs a full reset every time framebuffer is discarded.
1230 m_client->setFullRootLayerDamage();
1231 }
1232
1233 void LayerRendererChromium::ensureFramebuffer()
1234 {
1235 if (!m_isFramebufferDiscarded)
1236 return;
1237
1238 if (!m_capabilities.usingDiscardFramebuffer)
1239 return;
1240
1241 m_context->ensureFramebufferCHROMIUM();
1242 m_isFramebufferDiscarded = false;
1243 }
1244
1245 void LayerRendererChromium::onContextLost()
1246 {
1247 m_client->didLoseContext();
1248 }
1249
1250
1251 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& re ct)
1252 {
1253 ASSERT(rect.maxX() <= viewportWidth() && rect.maxY() <= viewportHeight());
1254
1255 if (!pixels)
1256 return;
1257
1258 makeContextCurrent();
1259
1260 bool doWorkaround = needsIOSurfaceReadbackWorkaround();
1261
1262 Platform3DObject temporaryTexture = 0;
1263 Platform3DObject temporaryFBO = 0;
1264
1265 if (doWorkaround) {
1266 // On Mac OS X, calling glReadPixels against an FBO whose color attachme nt is an
1267 // IOSurface-backed texture causes corruption of future glReadPixels cal ls, even those on
1268 // different OpenGL contexts. It is believed that this is the root cause of top crasher
1269 // http://crbug.com/99393. <rdar://problem/10949687>
1270
1271 temporaryTexture = m_context->createTexture();
1272 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, temporaryTexture));
1273 GLC(m_context, m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FI LTER, GL_LINEAR));
1274 GLC(m_context, m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FI LTER, GL_LINEAR));
1275 GLC(m_context, m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE));
1276 GLC(m_context, m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE));
1277 // Copy the contents of the current (IOSurface-backed) framebuffer into a temporary texture.
1278 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0 , rect.maxX(), rect.maxY(), 0));
1279 temporaryFBO = m_context->createFramebuffer();
1280 // Attach this texture to an FBO, and perform the readback from that FBO .
1281 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, temporaryFBO)) ;
1282 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ ATTACHMENT0, GL_TEXTURE_2D, temporaryTexture, 0));
1283
1284 ASSERT(m_context->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFF ER_COMPLETE);
1285 }
1286
1287 GLC(m_context, m_context->readPixels(rect.x(), rect.y(), rect.width(), rect. height(),
1288 GL_RGBA, GL_UNSIGNED_BYTE, pixels));
1289
1290 if (doWorkaround) {
1291 // Clean up.
1292 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0));
1293 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, 0));
1294 GLC(m_context, m_context->deleteFramebuffer(temporaryFBO));
1295 GLC(m_context, m_context->deleteTexture(temporaryTexture));
1296 }
1297
1298 if (!m_visible) {
1299 TRACE_EVENT0("cc", "LayerRendererChromium::getFramebufferPixels dropping resources after readback");
1300 discardFramebuffer();
1301 releaseRenderPassTextures();
1302 m_client->releaseContentsTextures();
1303 GLC(m_context, m_context->flush());
1304 }
1305 }
1306
1307 bool LayerRendererChromium::getFramebufferTexture(ManagedTexture* texture, const IntRect& deviceRect)
1308 {
1309 if (!texture->reserve(deviceRect.size(), GL_RGB))
1310 return false;
1311
1312 if (!texture->textureId())
1313 texture->allocate(m_implTextureAllocator.get());
1314 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, texture->textureId()));
1315 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, texture->format() ,
1316 deviceRect.x(), deviceRect.y(), dev iceRect.width(), deviceRect.height(), 0));
1317 return true;
1318 }
1319
1320 bool LayerRendererChromium::isCurrentRenderPass(const CCRenderPass* renderPass)
1321 {
1322 return m_currentRenderPass == renderPass && !m_currentManagedTexture;
1323 }
1324
1325 bool LayerRendererChromium::useRenderPass(const CCRenderPass* renderPass)
1326 {
1327 m_currentRenderPass = renderPass;
1328 m_currentManagedTexture = 0;
1329
1330 if (renderPass == m_defaultRenderPass) {
1331 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0));
1332 setDrawFramebufferRect(renderPass->framebufferOutputRect(), true);
1333 return true;
1334 }
1335
1336 if (!renderPass->targetSurface()->prepareContentsTexture(this))
1337 return false;
1338
1339 return bindFramebufferToTexture(renderPass->targetSurface()->contentsTexture (), renderPass->framebufferOutputRect());
1340 }
1341
1342 bool LayerRendererChromium::useManagedTexture(ManagedTexture* texture, const Int Rect& viewportRect)
1343 {
1344 m_currentRenderPass = 0;
1345 m_currentManagedTexture = texture;
1346
1347 return bindFramebufferToTexture(texture, viewportRect);
1348 }
1349
1350 bool LayerRendererChromium::bindFramebufferToTexture(ManagedTexture* texture, co nst IntRect& framebufferRect)
1351 {
1352 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, m_offscreenFramebu fferId));
1353
1354 if (!texture->textureId())
1355 texture->allocate(m_implTextureAllocator.get());
1356 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTA CHMENT0, GL_TEXTURE_2D, texture->textureId(), 0));
1357
1358 #if !defined ( NDEBUG )
1359 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE) {
1360 ASSERT_NOT_REACHED();
1361 return false;
1362 }
1363 #endif
1364
1365 setDrawFramebufferRect(framebufferRect, false);
1366
1367 return true;
1368 }
1369
1370 // Sets the scissor region to the given rectangle. The coordinate system for the
1371 // scissorRect has its origin at the top left corner of the current visible rect .
1372 void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
1373 {
1374 IntRect framebufferOutputRect = (m_currentRenderPass ? m_currentRenderPass-> framebufferOutputRect() : m_defaultRenderPass->framebufferOutputRect());
1375
1376 GLC(m_context, m_context->enable(GL_SCISSOR_TEST));
1377
1378 // The scissor coordinates must be supplied in viewport space so we need to offset
1379 // by the relative position of the top left corner of the current render pas s.
1380 int scissorX = scissorRect.x() - framebufferOutputRect.x();
1381 // When rendering to the default render surface we're rendering upside down so the top
1382 // of the GL scissor is the bottom of our layer.
1383 // But, if rendering to offscreen texture, we reverse our sense of 'upside d own'.
1384 int scissorY;
1385 if (isCurrentRenderPass(m_defaultRenderPass))
1386 scissorY = framebufferOutputRect.height() - (scissorRect.maxY() - frameb ufferOutputRect.y());
1387 else
1388 scissorY = scissorRect.y() - framebufferOutputRect.y();
1389 GLC(m_context, m_context->scissor(scissorX, scissorY, scissorRect.width(), s cissorRect.height()));
1390 }
1391
1392 bool LayerRendererChromium::makeContextCurrent()
1393 {
1394 return m_context->makeContextCurrent();
1395 }
1396
1397 // Sets the coordinate range of content that ends being drawn onto the target re nder surface.
1398 // The target render surface is assumed to have an origin at 0, 0 and the width and height of
1399 // of the drawRect.
1400 void LayerRendererChromium::setDrawFramebufferRect(const IntRect& drawRect, bool flipY)
1401 {
1402 if (flipY)
1403 m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect .maxY(), drawRect.y());
1404 else
1405 m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect .y(), drawRect.maxY());
1406 GLC(m_context, m_context->viewport(0, 0, drawRect.width(), drawRect.height() ));
1407 m_windowMatrix = screenMatrix(0, 0, drawRect.width(), drawRect.height());
1408 }
1409
1410
1411 bool LayerRendererChromium::initializeSharedObjects()
1412 {
1413 TRACE_EVENT0("cc", "LayerRendererChromium::initializeSharedObjects");
1414 makeContextCurrent();
1415
1416 // Create an FBO for doing offscreen rendering.
1417 GLC(m_context, m_offscreenFramebufferId = m_context->createFramebuffer());
1418
1419 // We will always need these programs to render, so create the programs eage rly so that the shader compilation can
1420 // start while we do other work. Other programs are created lazily on first access.
1421 m_sharedGeometry = adoptPtr(new GeometryBinding(m_context));
1422 m_renderPassProgram = adoptPtr(new RenderPassProgram(m_context));
1423 m_tileProgram = adoptPtr(new TileProgram(m_context));
1424 m_tileProgramOpaque = adoptPtr(new TileProgramOpaque(m_context));
1425
1426 GLC(m_context, m_context->flush());
1427
1428 m_implTextureManager = TextureManager::create(TextureManager::highLimitBytes (viewportSize()),
1429 TextureManager::reclaimLimitBy tes(viewportSize()),
1430 m_capabilities.maxTextureSize) ;
1431 m_textureCopier = AcceleratedTextureCopier::create(m_context);
1432 if (m_textureUploaderSetting == ThrottledUploader)
1433 m_textureUploader = ThrottledTextureUploader::create(m_context);
1434 else
1435 m_textureUploader = UnthrottledTextureUploader::create();
1436 m_contentsTextureAllocator = TrackingTextureAllocator::create(m_context);
1437 m_implTextureAllocator = TrackingTextureAllocator::create(m_context);
1438 if (m_capabilities.usingTextureUsageHint)
1439 m_implTextureAllocator->setTextureUsageHint(TrackingTextureAllocator::Fr amebufferAttachment);
1440 if (m_capabilities.usingTextureStorageExtension) {
1441 m_contentsTextureAllocator->setUseTextureStorageExt(true);
1442 m_implTextureAllocator->setUseTextureStorageExt(true);
1443 }
1444
1445 return true;
1446 }
1447
1448 const LayerRendererChromium::TileCheckerboardProgram* LayerRendererChromium::til eCheckerboardProgram()
1449 {
1450 if (!m_tileCheckerboardProgram)
1451 m_tileCheckerboardProgram = adoptPtr(new TileCheckerboardProgram(m_conte xt));
1452 if (!m_tileCheckerboardProgram->initialized()) {
1453 TRACE_EVENT0("cc", "LayerRendererChromium::checkerboardProgram::initaliz e");
1454 m_tileCheckerboardProgram->initialize(m_context);
1455 }
1456 return m_tileCheckerboardProgram.get();
1457 }
1458
1459 const LayerRendererChromium::SolidColorProgram* LayerRendererChromium::solidColo rProgram()
1460 {
1461 if (!m_solidColorProgram)
1462 m_solidColorProgram = adoptPtr(new SolidColorProgram(m_context));
1463 if (!m_solidColorProgram->initialized()) {
1464 TRACE_EVENT0("cc", "LayerRendererChromium::solidColorProgram::initialize ");
1465 m_solidColorProgram->initialize(m_context);
1466 }
1467 return m_solidColorProgram.get();
1468 }
1469
1470 const LayerRendererChromium::HeadsUpDisplayProgram* LayerRendererChromium::heads UpDisplayProgram()
1471 {
1472 if (!m_headsUpDisplayProgram)
1473 m_headsUpDisplayProgram = adoptPtr(new HeadsUpDisplayProgram(m_context)) ;
1474 if (!m_headsUpDisplayProgram->initialized()) {
1475 TRACE_EVENT0("cc", "LayerRendererChromium::headsUpDisplayProgram::initia lize");
1476 m_headsUpDisplayProgram->initialize(m_context);
1477 }
1478 return m_headsUpDisplayProgram.get();
1479 }
1480
1481 const LayerRendererChromium::RenderPassProgram* LayerRendererChromium::renderPas sProgram()
1482 {
1483 ASSERT(m_renderPassProgram);
1484 if (!m_renderPassProgram->initialized()) {
1485 TRACE_EVENT0("cc", "LayerRendererChromium::renderPassProgram::initialize ");
1486 m_renderPassProgram->initialize(m_context);
1487 }
1488 return m_renderPassProgram.get();
1489 }
1490
1491 const LayerRendererChromium::RenderPassProgramAA* LayerRendererChromium::renderP assProgramAA()
1492 {
1493 if (!m_renderPassProgramAA)
1494 m_renderPassProgramAA = adoptPtr(new RenderPassProgramAA(m_context));
1495 if (!m_renderPassProgramAA->initialized()) {
1496 TRACE_EVENT0("cc", "LayerRendererChromium::renderPassProgramAA::initiali ze");
1497 m_renderPassProgramAA->initialize(m_context);
1498 }
1499 return m_renderPassProgramAA.get();
1500 }
1501
1502 const LayerRendererChromium::RenderPassMaskProgram* LayerRendererChromium::rende rPassMaskProgram()
1503 {
1504 if (!m_renderPassMaskProgram)
1505 m_renderPassMaskProgram = adoptPtr(new RenderPassMaskProgram(m_context)) ;
1506 if (!m_renderPassMaskProgram->initialized()) {
1507 TRACE_EVENT0("cc", "LayerRendererChromium::renderPassMaskProgram::initia lize");
1508 m_renderPassMaskProgram->initialize(m_context);
1509 }
1510 return m_renderPassMaskProgram.get();
1511 }
1512
1513 const LayerRendererChromium::RenderPassMaskProgramAA* LayerRendererChromium::ren derPassMaskProgramAA()
1514 {
1515 if (!m_renderPassMaskProgramAA)
1516 m_renderPassMaskProgramAA = adoptPtr(new RenderPassMaskProgramAA(m_conte xt));
1517 if (!m_renderPassMaskProgramAA->initialized()) {
1518 TRACE_EVENT0("cc", "LayerRendererChromium::renderPassMaskProgramAA::init ialize");
1519 m_renderPassMaskProgramAA->initialize(m_context);
1520 }
1521 return m_renderPassMaskProgramAA.get();
1522 }
1523
1524 const LayerRendererChromium::TileProgram* LayerRendererChromium::tileProgram()
1525 {
1526 ASSERT(m_tileProgram);
1527 if (!m_tileProgram->initialized()) {
1528 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgram::initialize");
1529 m_tileProgram->initialize(m_context);
1530 }
1531 return m_tileProgram.get();
1532 }
1533
1534 const LayerRendererChromium::TileProgramOpaque* LayerRendererChromium::tileProgr amOpaque()
1535 {
1536 ASSERT(m_tileProgramOpaque);
1537 if (!m_tileProgramOpaque->initialized()) {
1538 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgramOpaque::initialize ");
1539 m_tileProgramOpaque->initialize(m_context);
1540 }
1541 return m_tileProgramOpaque.get();
1542 }
1543
1544 const LayerRendererChromium::TileProgramAA* LayerRendererChromium::tileProgramAA ()
1545 {
1546 if (!m_tileProgramAA)
1547 m_tileProgramAA = adoptPtr(new TileProgramAA(m_context));
1548 if (!m_tileProgramAA->initialized()) {
1549 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgramAA::initialize");
1550 m_tileProgramAA->initialize(m_context);
1551 }
1552 return m_tileProgramAA.get();
1553 }
1554
1555 const LayerRendererChromium::TileProgramSwizzle* LayerRendererChromium::tileProg ramSwizzle()
1556 {
1557 if (!m_tileProgramSwizzle)
1558 m_tileProgramSwizzle = adoptPtr(new TileProgramSwizzle(m_context));
1559 if (!m_tileProgramSwizzle->initialized()) {
1560 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgramSwizzle::initializ e");
1561 m_tileProgramSwizzle->initialize(m_context);
1562 }
1563 return m_tileProgramSwizzle.get();
1564 }
1565
1566 const LayerRendererChromium::TileProgramSwizzleOpaque* LayerRendererChromium::ti leProgramSwizzleOpaque()
1567 {
1568 if (!m_tileProgramSwizzleOpaque)
1569 m_tileProgramSwizzleOpaque = adoptPtr(new TileProgramSwizzleOpaque(m_con text));
1570 if (!m_tileProgramSwizzleOpaque->initialized()) {
1571 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgramSwizzleOpaque::ini tialize");
1572 m_tileProgramSwizzleOpaque->initialize(m_context);
1573 }
1574 return m_tileProgramSwizzleOpaque.get();
1575 }
1576
1577 const LayerRendererChromium::TileProgramSwizzleAA* LayerRendererChromium::tilePr ogramSwizzleAA()
1578 {
1579 if (!m_tileProgramSwizzleAA)
1580 m_tileProgramSwizzleAA = adoptPtr(new TileProgramSwizzleAA(m_context));
1581 if (!m_tileProgramSwizzleAA->initialized()) {
1582 TRACE_EVENT0("cc", "LayerRendererChromium::tileProgramSwizzleAA::initial ize");
1583 m_tileProgramSwizzleAA->initialize(m_context);
1584 }
1585 return m_tileProgramSwizzleAA.get();
1586 }
1587
1588 const LayerRendererChromium::TextureProgram* LayerRendererChromium::textureProgr am()
1589 {
1590 if (!m_textureProgram)
1591 m_textureProgram = adoptPtr(new TextureProgram(m_context));
1592 if (!m_textureProgram->initialized()) {
1593 TRACE_EVENT0("cc", "LayerRendererChromium::textureProgram::initialize");
1594 m_textureProgram->initialize(m_context);
1595 }
1596 return m_textureProgram.get();
1597 }
1598
1599 const LayerRendererChromium::TextureProgramFlip* LayerRendererChromium::textureP rogramFlip()
1600 {
1601 if (!m_textureProgramFlip)
1602 m_textureProgramFlip = adoptPtr(new TextureProgramFlip(m_context));
1603 if (!m_textureProgramFlip->initialized()) {
1604 TRACE_EVENT0("cc", "LayerRendererChromium::textureProgramFlip::initializ e");
1605 m_textureProgramFlip->initialize(m_context);
1606 }
1607 return m_textureProgramFlip.get();
1608 }
1609
1610 const LayerRendererChromium::TextureIOSurfaceProgram* LayerRendererChromium::tex tureIOSurfaceProgram()
1611 {
1612 if (!m_textureIOSurfaceProgram)
1613 m_textureIOSurfaceProgram = adoptPtr(new TextureIOSurfaceProgram(m_conte xt));
1614 if (!m_textureIOSurfaceProgram->initialized()) {
1615 TRACE_EVENT0("cc", "LayerRendererChromium::textureIOSurfaceProgram::init ialize");
1616 m_textureIOSurfaceProgram->initialize(m_context);
1617 }
1618 return m_textureIOSurfaceProgram.get();
1619 }
1620
1621 const LayerRendererChromium::VideoYUVProgram* LayerRendererChromium::videoYUVPro gram()
1622 {
1623 if (!m_videoYUVProgram)
1624 m_videoYUVProgram = adoptPtr(new VideoYUVProgram(m_context));
1625 if (!m_videoYUVProgram->initialized()) {
1626 TRACE_EVENT0("cc", "LayerRendererChromium::videoYUVProgram::initialize") ;
1627 m_videoYUVProgram->initialize(m_context);
1628 }
1629 return m_videoYUVProgram.get();
1630 }
1631
1632 const LayerRendererChromium::VideoStreamTextureProgram* LayerRendererChromium::v ideoStreamTextureProgram()
1633 {
1634 if (!m_videoStreamTextureProgram)
1635 m_videoStreamTextureProgram = adoptPtr(new VideoStreamTextureProgram(m_c ontext));
1636 if (!m_videoStreamTextureProgram->initialized()) {
1637 TRACE_EVENT0("cc", "LayerRendererChromium::streamTextureProgram::initial ize");
1638 m_videoStreamTextureProgram->initialize(m_context);
1639 }
1640 return m_videoStreamTextureProgram.get();
1641 }
1642
1643 void LayerRendererChromium::cleanupSharedObjects()
1644 {
1645 makeContextCurrent();
1646
1647 m_sharedGeometry.clear();
1648
1649 if (m_tileProgram)
1650 m_tileProgram->cleanup(m_context);
1651 if (m_tileProgramOpaque)
1652 m_tileProgramOpaque->cleanup(m_context);
1653 if (m_tileProgramSwizzle)
1654 m_tileProgramSwizzle->cleanup(m_context);
1655 if (m_tileProgramSwizzleOpaque)
1656 m_tileProgramSwizzleOpaque->cleanup(m_context);
1657 if (m_tileProgramAA)
1658 m_tileProgramAA->cleanup(m_context);
1659 if (m_tileProgramSwizzleAA)
1660 m_tileProgramSwizzleAA->cleanup(m_context);
1661 if (m_tileCheckerboardProgram)
1662 m_tileCheckerboardProgram->cleanup(m_context);
1663
1664 if (m_renderPassMaskProgram)
1665 m_renderPassMaskProgram->cleanup(m_context);
1666 if (m_renderPassProgram)
1667 m_renderPassProgram->cleanup(m_context);
1668 if (m_renderPassMaskProgramAA)
1669 m_renderPassMaskProgramAA->cleanup(m_context);
1670 if (m_renderPassProgramAA)
1671 m_renderPassProgramAA->cleanup(m_context);
1672
1673 if (m_textureProgram)
1674 m_textureProgram->cleanup(m_context);
1675 if (m_textureProgramFlip)
1676 m_textureProgramFlip->cleanup(m_context);
1677 if (m_textureIOSurfaceProgram)
1678 m_textureIOSurfaceProgram->cleanup(m_context);
1679
1680 if (m_videoYUVProgram)
1681 m_videoYUVProgram->cleanup(m_context);
1682 if (m_videoStreamTextureProgram)
1683 m_videoStreamTextureProgram->cleanup(m_context);
1684
1685 if (m_solidColorProgram)
1686 m_solidColorProgram->cleanup(m_context);
1687
1688 if (m_headsUpDisplayProgram)
1689 m_headsUpDisplayProgram->cleanup(m_context);
1690
1691 if (m_offscreenFramebufferId)
1692 GLC(m_context, m_context->deleteFramebuffer(m_offscreenFramebufferId));
1693
1694 m_textureCopier.clear();
1695 m_textureUploader.clear();
1696
1697 releaseRenderPassTextures();
1698 }
1699
1700 bool LayerRendererChromium::isContextLost()
1701 {
1702 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR);
1703 }
1704
1705 } // namespace WebCore
1706
1707 #endif // USE(ACCELERATED_COMPOSITING)
OLDNEW
« no previous file with comments | « ui/cc/LayerRendererChromium.h ('k') | ui/cc/LayerTextureSubImage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698