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

Side by Side Diff: Source/core/html/HTMLCanvasElement.cpp

Issue 44253005: 2D Canvas: Refactor code re-attempting to allocate an imageBuffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@convertL
Patch Set: Created 7 years, 1 month 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) 2004, 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 //In Skia, we will also limit width/height to 32767. 66 //In Skia, we will also limit width/height to 32767.
67 static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels. 67 static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels.
68 68
69 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& doc ument) 69 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& doc ument)
70 : HTMLElement(tagName, document) 70 : HTMLElement(tagName, document)
71 , m_size(DefaultWidth, DefaultHeight) 71 , m_size(DefaultWidth, DefaultHeight)
72 , m_rendererIsCanvas(false) 72 , m_rendererIsCanvas(false)
73 , m_ignoreReset(false) 73 , m_ignoreReset(false)
74 , m_deviceScaleFactor(1) 74 , m_deviceScaleFactor(1)
75 , m_originClean(true) 75 , m_originClean(true)
76 , m_hasCreatedImageBuffer(false)
77 , m_didClearImageBuffer(false) 76 , m_didClearImageBuffer(false)
78 , m_accelerationDisabled(false) 77 , m_accelerationDisabled(false)
79 , m_externallyAllocatedMemory(0) 78 , m_externallyAllocatedMemory(0)
80 { 79 {
81 ASSERT(hasTagName(canvasTag)); 80 ASSERT(hasTagName(canvasTag));
82 ScriptWrappable::init(this); 81 ScriptWrappable::init(this);
83 } 82 }
84 83
85 PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document) 84 PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
86 { 85 {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it) 230 for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
232 (*it)->canvasChanged(this, rect); 231 (*it)->canvasChanged(this, rect);
233 } 232 }
234 233
235 void HTMLCanvasElement::reset() 234 void HTMLCanvasElement::reset()
236 { 235 {
237 if (m_ignoreReset) 236 if (m_ignoreReset)
238 return; 237 return;
239 238
240 bool ok; 239 bool ok;
241 bool hadImageBuffer = hasCreatedImageBuffer(); 240 bool hadImageBuffer = m_imageBuffer.get();
242 241
243 int w = getAttribute(widthAttr).toInt(&ok); 242 int w = getAttribute(widthAttr).toInt(&ok);
244 if (!ok || w < 0) 243 if (!ok || w < 0)
245 w = DefaultWidth; 244 w = DefaultWidth;
246 245
247 int h = getAttribute(heightAttr).toInt(&ok); 246 int h = getAttribute(heightAttr).toInt(&ok);
248 if (!ok || h < 0) 247 if (!ok || h < 0)
249 h = DefaultHeight; 248 h = DefaultHeight;
250 249
251 if (m_contextStateSaver) { 250 if (m_contextStateSaver) {
252 // Reset to the initial graphics context state. 251 // Reset to the initial graphics context state.
253 m_contextStateSaver->restore(); 252 m_contextStateSaver->restore();
254 m_contextStateSaver->save(); 253 m_contextStateSaver->save();
255 } 254 }
256 255
257 if (m_context && m_context->is2d()) { 256 if (m_context && m_context->is2d()) {
258 CanvasRenderingContext2D* context2D = static_cast<CanvasRenderingContext 2D*>(m_context.get()); 257 CanvasRenderingContext2D* context2D = static_cast<CanvasRenderingContext 2D*>(m_context.get());
259 context2D->reset(); 258 context2D->reset();
260 } 259 }
261 260
262 IntSize oldSize = size(); 261 IntSize oldSize = size();
263 IntSize newSize(w, h); 262 IntSize newSize(w, h);
264 float newDeviceScaleFactor = 1; 263 float newDeviceScaleFactor = 1;
265 264
266 // If the size of an existing buffer matches, we can just clear it instead o f reallocating. 265 // If the size of an existing buffer matches, we can just clear it instead o f reallocating.
267 // This optimization is only done for 2D canvases for now. 266 // This optimization is only done for 2D canvases for now.
268 if (m_hasCreatedImageBuffer && oldSize == newSize && m_deviceScaleFactor == newDeviceScaleFactor && m_context && m_context->is2d()) { 267 if (m_imageBuffer && oldSize == newSize && m_deviceScaleFactor == newDeviceS caleFactor && m_context && m_context->is2d()) {
269 if (!m_didClearImageBuffer) 268 if (!m_didClearImageBuffer)
270 clearImageBuffer(); 269 clearImageBuffer();
271 return; 270 return;
272 } 271 }
273 272
274 m_deviceScaleFactor = newDeviceScaleFactor; 273 m_deviceScaleFactor = newDeviceScaleFactor;
275 274
276 setSurfaceSize(newSize); 275 setSurfaceSize(newSize);
277 276
278 if (m_context && m_context->is3d() && oldSize != size()) 277 if (m_context && m_context->is3d() && oldSize != size())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 315
317 if (context->paintingDisabled()) 316 if (context->paintingDisabled())
318 return; 317 return;
319 318
320 if (m_context) { 319 if (m_context) {
321 if (!paintsIntoCanvasBuffer() && !document().printing()) 320 if (!paintsIntoCanvasBuffer() && !document().printing())
322 return; 321 return;
323 m_context->paintRenderingResultsToCanvas(); 322 m_context->paintRenderingResultsToCanvas();
324 } 323 }
325 324
326 if (hasCreatedImageBuffer()) { 325 ImageBuffer* imageBuffer = buffer();
327 ImageBuffer* imageBuffer = buffer(); 326 if (imageBuffer) {
328 if (imageBuffer) { 327 CompositeOperator compositeOperator = !m_context || m_context->hasAlpha( ) ? CompositeSourceOver : CompositeCopy;
329 CompositeOperator compositeOperator = !m_context || m_context->hasAl pha() ? CompositeSourceOver : CompositeCopy; 328 if (m_presentedImage)
330 if (m_presentedImage) 329 context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), c ompositeOperator, DoNotRespectImageOrientation, useLowQualityScale);
331 context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r ), compositeOperator, DoNotRespectImageOrientation, useLowQualityScale); 330 else
332 else 331 context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), compos iteOperator, BlendModeNormal, useLowQualityScale);
333 context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), co mpositeOperator, BlendModeNormal, useLowQualityScale);
334 }
335 } 332 }
336 333
337 if (is3D()) 334 if (is3D())
338 static_cast<WebGLRenderingContext*>(m_context.get())->markLayerComposite d(); 335 static_cast<WebGLRenderingContext*>(m_context.get())->markLayerComposite d();
339 } 336 }
340 337
341 bool HTMLCanvasElement::is3D() const 338 bool HTMLCanvasElement::is3D() const
342 { 339 {
343 return m_context && m_context->is3d(); 340 return m_context && m_context->is3d();
344 } 341 }
345 342
346 void HTMLCanvasElement::makePresentationCopy() 343 void HTMLCanvasElement::makePresentationCopy()
347 { 344 {
348 if (!m_presentedImage) { 345 if (!m_presentedImage) {
349 // The buffer contains the last presented data, so save a copy of it. 346 // The buffer contains the last presented data, so save a copy of it.
350 m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled); 347 m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
351 } 348 }
352 } 349 }
353 350
354 void HTMLCanvasElement::clearPresentationCopy() 351 void HTMLCanvasElement::clearPresentationCopy()
355 { 352 {
356 m_presentedImage.clear(); 353 m_presentedImage.clear();
357 } 354 }
358 355
359 void HTMLCanvasElement::setSurfaceSize(const IntSize& size) 356 void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
360 { 357 {
361 m_size = size; 358 m_size = size;
362 m_hasCreatedImageBuffer = false;
363 m_contextStateSaver.clear(); 359 m_contextStateSaver.clear();
364 m_imageBuffer.clear(); 360 m_imageBuffer.clear();
365 setExternallyAllocatedMemory(0); 361 setExternallyAllocatedMemory(0);
366 clearCopiedImage(); 362 clearCopiedImage();
367 } 363 }
368 364
369 String HTMLCanvasElement::toEncodingMimeType(const String& mimeType) 365 String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
370 { 366 {
371 String lowercaseMimeType = mimeType.lower(); 367 String lowercaseMimeType = mimeType.lower();
372 368
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (!WebKit::Platform::current()->canAccelerate2dCanvas()) 467 if (!WebKit::Platform::current()->canAccelerate2dCanvas())
472 return false; 468 return false;
473 469
474 return true; 470 return true;
475 } 471 }
476 472
477 void HTMLCanvasElement::createImageBuffer() 473 void HTMLCanvasElement::createImageBuffer()
478 { 474 {
479 ASSERT(!m_imageBuffer); 475 ASSERT(!m_imageBuffer);
480 476
481 m_hasCreatedImageBuffer = true;
482 m_didClearImageBuffer = true; 477 m_didClearImageBuffer = true;
483 478
484 FloatSize logicalSize = size(); 479 FloatSize logicalSize = size();
485 FloatSize deviceSize = convertLogicalToDevice(logicalSize); 480 FloatSize deviceSize = convertLogicalToDevice(logicalSize);
486 if (!deviceSize.isExpressibleAsIntSize()) 481 if (!deviceSize.isExpressibleAsIntSize())
487 return; 482 return;
488 483
489 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) 484 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea)
490 return; 485 return;
491 486
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 m_externallyAllocatedMemory = externallyAllocatedMemory; 521 m_externallyAllocatedMemory = externallyAllocatedMemory;
527 } 522 }
528 523
529 GraphicsContext* HTMLCanvasElement::drawingContext() const 524 GraphicsContext* HTMLCanvasElement::drawingContext() const
530 { 525 {
531 return buffer() ? m_imageBuffer->context() : 0; 526 return buffer() ? m_imageBuffer->context() : 0;
532 } 527 }
533 528
534 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const 529 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const
535 { 530 {
536 if (!m_hasCreatedImageBuffer) 531 if (!m_imageBuffer)
537 return 0; 532 return 0;
538 533
539 return drawingContext(); 534 return drawingContext();
540 } 535 }
541 536
542 ImageBuffer* HTMLCanvasElement::buffer() const 537 ImageBuffer* HTMLCanvasElement::buffer() const
543 { 538 {
544 if (!m_hasCreatedImageBuffer) 539 if (!m_imageBuffer)
545 const_cast<HTMLCanvasElement*>(this)->createImageBuffer(); 540 const_cast<HTMLCanvasElement*>(this)->createImageBuffer();
546 return m_imageBuffer.get(); 541 return m_imageBuffer.get();
547 } 542 }
548 543
549 Image* HTMLCanvasElement::copiedImage() const 544 Image* HTMLCanvasElement::copiedImage() const
550 { 545 {
551 if (!m_copiedImage && buffer()) { 546 if (!m_copiedImage && buffer()) {
552 if (m_context) 547 if (m_context)
553 m_context->paintRenderingResultsToCanvas(); 548 m_context->paintRenderingResultsToCanvas();
554 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); 549 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
555 } 550 }
556 return m_copiedImage.get(); 551 return m_copiedImage.get();
557 } 552 }
558 553
559 void HTMLCanvasElement::clearImageBuffer() 554 void HTMLCanvasElement::clearImageBuffer()
560 { 555 {
561 ASSERT(m_hasCreatedImageBuffer); 556 ASSERT(m_imageBuffer);
562 ASSERT(!m_didClearImageBuffer); 557 ASSERT(!m_didClearImageBuffer);
563 ASSERT(m_context); 558 ASSERT(m_context);
564 559
565 m_didClearImageBuffer = true; 560 m_didClearImageBuffer = true;
566 561
567 if (m_context->is2d()) { 562 if (m_context->is2d()) {
568 CanvasRenderingContext2D* context2D = static_cast<CanvasRenderingContext 2D*>(m_context.get()); 563 CanvasRenderingContext2D* context2D = static_cast<CanvasRenderingContext 2D*>(m_context.get());
569 // No need to undo transforms/clip/etc. because we are called right afte r the context is reset. 564 // No need to undo transforms/clip/etc. because we are called right afte r the context is reset.
570 context2D->clearRect(0, 0, width(), height()); 565 context2D->clearRect(0, 0, width(), height());
571 } 566 }
572 } 567 }
573 568
574 void HTMLCanvasElement::clearCopiedImage() 569 void HTMLCanvasElement::clearCopiedImage()
575 { 570 {
576 m_copiedImage.clear(); 571 m_copiedImage.clear();
577 m_didClearImageBuffer = false; 572 m_didClearImageBuffer = false;
578 } 573 }
579 574
580 AffineTransform HTMLCanvasElement::baseTransform() const 575 AffineTransform HTMLCanvasElement::baseTransform() const
581 { 576 {
582 ASSERT(m_hasCreatedImageBuffer); 577 ASSERT(m_imageBuffer);
583 FloatSize unscaledSize = size(); 578 FloatSize unscaledSize = size();
584 FloatSize deviceSize = convertLogicalToDevice(unscaledSize); 579 FloatSize deviceSize = convertLogicalToDevice(unscaledSize);
585 IntSize size(deviceSize.width(), deviceSize.height()); 580 IntSize size(deviceSize.width(), deviceSize.height());
586 AffineTransform transform; 581 AffineTransform transform;
587 if (size.width() && size.height()) 582 if (size.width() && size.height())
588 transform.scaleNonUniform(size.width() / unscaledSize.width(), size.heig ht() / unscaledSize.height()); 583 transform.scaleNonUniform(size.width() / unscaledSize.width(), size.heig ht() / unscaledSize.height());
589 return m_imageBuffer->baseTransform() * transform; 584 return m_imageBuffer->baseTransform() * transform;
590 } 585 }
591 586
592 } 587 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698