OLD | NEW |
---|---|
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 #include <math.h> | 62 #include <math.h> |
63 #include <v8.h> | 63 #include <v8.h> |
64 | 64 |
65 namespace blink { | 65 namespace blink { |
66 | 66 |
67 using namespace HTMLNames; | 67 using namespace HTMLNames; |
68 | 68 |
69 namespace { | 69 namespace { |
70 | 70 |
71 // These values come from the WhatWG spec. | 71 // These values come from the WhatWG spec. |
72 const int DefaultWidth = 300; | 72 const int kDefaultWidth = 300; |
Justin Novosad
2015/12/02 16:33:33
The k prefix is a skia thing. In Blink use Capital
danakj
2015/12/02 18:23:40
It's also a chromium thing, I didn't know blink ha
danakj
2015/12/02 18:31:09
FWIW I only see a blink-specific rule for enums: "
| |
73 const int DefaultHeight = 150; | 73 const int kDefaultHeight = 150; |
74 | 74 |
75 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it | 75 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it |
76 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, | 76 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, |
77 // in exchange for a smaller maximum canvas size. | 77 // in exchange for a smaller maximum canvas size. |
78 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels | 78 const int kMaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels |
79 | 79 |
80 // In Skia, we will also limit width/height to 32767. | 80 // In Skia, we will also limit width/height to 32767. |
81 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | 81 const int kMaxSkiaDim = 32767; // Maximum width/height in CSS pixels. |
82 | |
83 // We estimate the max limit of GPU allocated memory for canvases before Chrome becomes laggy by setting the | |
84 // total allocated memory for accelerated canvases to be equivalent to memory us ed by 80 accelerated | |
85 // canvases, each has a size of 1000*500 and 2d context. | |
86 // Each such canvas occupies 6000000 = 1000 * 500 * 3 * 4 bytes, where 3 is the bufferCount in | |
87 // updateExternallyAllocatedMemory() and 4 means four bytes per pixel per buffer . | |
88 #if !OS(ANDROID) | |
89 const int kMaxTotalExternallyAllocatedMemory = 6000000 * 80; | |
90 #else | |
91 // We estimate that the max limit for android phones is half of that for desktop s based on local | |
92 // experimental results on Android One; though a very slight lagginess on Androi d One is still expected, | |
93 // other Android devices should work fine. | |
94 const int kMaxTotalExternallyAllocatedMemory = 6000000 * 40; | |
95 #endif | |
82 | 96 |
83 // A default value of quality argument for toDataURL and toBlob | 97 // A default value of quality argument for toDataURL and toBlob |
84 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be misinter preted as a user-input value | 98 // It is in an invalid range (outside 0.0 - 1.0) so that it will not be misinter preted as a user-input value |
85 const int UndefinedQualityValue = -1.0; | 99 const int kUndefinedQualityValue = -1.0; |
86 | 100 |
87 // Default image mime type for toDataURL and toBlob functions | 101 // Default image mime type for toDataURL and toBlob functions |
88 const char DefaultMimeType[] = "image/png"; | 102 const char kDefaultMimeType[] = "image/png"; |
89 | 103 |
90 bool canCreateImageBuffer(const IntSize& size) | 104 bool canCreateImageBuffer(const IntSize& size) |
91 { | 105 { |
92 if (size.isEmpty()) | 106 if (size.isEmpty()) |
93 return false; | 107 return false; |
94 if (size.width() * size.height() > MaxCanvasArea) | 108 if (size.width() * size.height() > kMaxCanvasArea) |
95 return false; | 109 return false; |
96 if (size.width() > MaxSkiaDim || size.height() > MaxSkiaDim) | 110 if (size.width() > kMaxSkiaDim || size.height() > kMaxSkiaDim) |
97 return false; | 111 return false; |
98 return true; | 112 return true; |
99 } | 113 } |
100 | 114 |
101 PassRefPtr<Image> createTransparentImage(const IntSize& size) | 115 PassRefPtr<Image> createTransparentImage(const IntSize& size) |
102 { | 116 { |
103 ASSERT(canCreateImageBuffer(size)); | 117 ASSERT(canCreateImageBuffer(size)); |
104 RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.widt h(), size.height())); | 118 RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.widt h(), size.height())); |
105 surface->getCanvas()->clear(SK_ColorTRANSPARENT); | 119 surface->getCanvas()->clear(SK_ColorTRANSPARENT); |
106 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot())); | 120 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot())); |
107 } | 121 } |
108 | 122 |
109 } // namespace | 123 } // namespace |
110 | 124 |
111 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 125 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
112 : HTMLElement(canvasTag, document) | 126 : HTMLElement(canvasTag, document) |
113 , DocumentVisibilityObserver(document) | 127 , DocumentVisibilityObserver(document) |
114 , m_size(DefaultWidth, DefaultHeight) | 128 , m_size(kDefaultWidth, kDefaultHeight) |
115 , m_ignoreReset(false) | 129 , m_ignoreReset(false) |
116 , m_externallyAllocatedMemory(0) | 130 , m_externallyAllocatedMemory(0) |
117 , m_originClean(true) | 131 , m_originClean(true) |
118 , m_didFailToCreateImageBuffer(false) | 132 , m_didFailToCreateImageBuffer(false) |
119 , m_imageBufferIsClear(false) | 133 , m_imageBufferIsClear(false) |
120 { | 134 { |
121 setHasCustomStyleCallbacks(); | 135 setHasCustomStyleCallbacks(); |
122 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::CanvasCreated); | 136 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::CanvasCreated); |
123 } | 137 } |
124 | 138 |
125 DEFINE_NODE_FACTORY(HTMLCanvasElement) | 139 DEFINE_NODE_FACTORY(HTMLCanvasElement) |
126 | 140 |
141 intptr_t HTMLCanvasElement::s_totalMemoryForAcceleratedCanvases = 0; | |
142 | |
127 HTMLCanvasElement::~HTMLCanvasElement() | 143 HTMLCanvasElement::~HTMLCanvasElement() |
128 { | 144 { |
129 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external lyAllocatedMemory); | 145 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external lyAllocatedMemory); |
146 if (m_imageBuffer && m_imageBuffer->isAccelerated()) | |
147 updateTotalMemoryForAcceleratedCanvases(-m_externallyAllocatedMemory); | |
130 #if !ENABLE(OILPAN) | 148 #if !ENABLE(OILPAN) |
131 // Ensure these go away before the ImageBuffer. | 149 // Ensure these go away before the ImageBuffer. |
132 m_context.clear(); | 150 m_context.clear(); |
133 #endif | 151 #endif |
134 } | 152 } |
135 | 153 |
136 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value) | 154 void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value) |
137 { | 155 { |
138 if (name == widthAttr || name == heightAttr) | 156 if (name == widthAttr || name == heightAttr) |
139 reset(); | 157 reset(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 if (m_ignoreReset) | 358 if (m_ignoreReset) |
341 return; | 359 return; |
342 | 360 |
343 m_dirtyRect = FloatRect(); | 361 m_dirtyRect = FloatRect(); |
344 | 362 |
345 bool ok; | 363 bool ok; |
346 bool hadImageBuffer = hasImageBuffer(); | 364 bool hadImageBuffer = hasImageBuffer(); |
347 | 365 |
348 int w = getAttribute(widthAttr).toInt(&ok); | 366 int w = getAttribute(widthAttr).toInt(&ok); |
349 if (!ok || w < 0) | 367 if (!ok || w < 0) |
350 w = DefaultWidth; | 368 w = kDefaultWidth; |
351 | 369 |
352 int h = getAttribute(heightAttr).toInt(&ok); | 370 int h = getAttribute(heightAttr).toInt(&ok); |
353 if (!ok || h < 0) | 371 if (!ok || h < 0) |
354 h = DefaultHeight; | 372 h = kDefaultHeight; |
355 | 373 |
356 if (m_context && m_context->is2d()) | 374 if (m_context && m_context->is2d()) |
357 m_context->reset(); | 375 m_context->reset(); |
358 | 376 |
359 IntSize oldSize = size(); | 377 IntSize oldSize = size(); |
360 IntSize newSize(w, h); | 378 IntSize newSize(w, h); |
361 | 379 |
362 // If the size of an existing buffer matches, we can just clear it instead o f reallocating. | 380 // If the size of an existing buffer matches, we can just clear it instead o f reallocating. |
363 // This optimization is only done for 2D canvases for now. | 381 // This optimization is only done for 2D canvases for now. |
364 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() & & !buffer()->isRecording()) { | 382 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() & & !buffer()->isRecording()) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 m_context->didSetSurfaceSize(); | 462 m_context->didSetSurfaceSize(); |
445 } | 463 } |
446 } | 464 } |
447 | 465 |
448 String HTMLCanvasElement::toEncodingMimeType(const String& mimeType) | 466 String HTMLCanvasElement::toEncodingMimeType(const String& mimeType) |
449 { | 467 { |
450 String lowercaseMimeType = mimeType.lower(); | 468 String lowercaseMimeType = mimeType.lower(); |
451 | 469 |
452 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). | 470 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). |
453 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) | 471 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) |
454 lowercaseMimeType = DefaultMimeType; | 472 lowercaseMimeType = kDefaultMimeType; |
455 | 473 |
456 return lowercaseMimeType; | 474 return lowercaseMimeType; |
457 } | 475 } |
458 | 476 |
459 const AtomicString HTMLCanvasElement::imageSourceURL() const | 477 const AtomicString HTMLCanvasElement::imageSourceURL() const |
460 { | 478 { |
461 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); | 479 return AtomicString(toDataURLInternal(kDefaultMimeType, 0, FrontBuffer)); |
462 } | 480 } |
463 | 481 |
464 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 482 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
465 { | 483 { |
466 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d context | 484 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d context |
467 if (buffer()) | 485 if (buffer()) |
468 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 486 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
469 } | 487 } |
470 | 488 |
471 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons t | 489 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons t |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 | 532 |
515 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); | 533 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); |
516 } | 534 } |
517 | 535 |
518 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const | 536 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const |
519 { | 537 { |
520 if (!originClean()) { | 538 if (!originClean()) { |
521 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 539 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
522 return String(); | 540 return String(); |
523 } | 541 } |
524 double quality = UndefinedQualityValue; | 542 double quality = kUndefinedQualityValue; |
525 if (!qualityArgument.isEmpty()) { | 543 if (!qualityArgument.isEmpty()) { |
526 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 544 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
527 if (v8Value->IsNumber()) { | 545 if (v8Value->IsNumber()) { |
528 quality = v8Value.As<v8::Number>()->Value(); | 546 quality = v8Value.As<v8::Number>()->Value(); |
529 } | 547 } |
530 } | 548 } |
531 return toDataURLInternal(mimeType, quality, BackBuffer); | 549 return toDataURLInternal(mimeType, quality, BackBuffer); |
532 } | 550 } |
533 | 551 |
534 void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, c onst ScriptValue& qualityArgument, ExceptionState& exceptionState) | 552 void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, c onst ScriptValue& qualityArgument, ExceptionState& exceptionState) |
535 { | 553 { |
536 if (!originClean()) { | 554 if (!originClean()) { |
537 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 555 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
538 return; | 556 return; |
539 } | 557 } |
540 | 558 |
541 if (!isPaintable()) { | 559 if (!isPaintable()) { |
542 // If the canvas element's bitmap has no pixels | 560 // If the canvas element's bitmap has no pixels |
543 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER E, bind(&FileCallback::handleEvent, callback, nullptr)); | 561 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER E, bind(&FileCallback::handleEvent, callback, nullptr)); |
544 return; | 562 return; |
545 } | 563 } |
546 | 564 |
547 double quality = UndefinedQualityValue; | 565 double quality = kUndefinedQualityValue; |
548 if (!qualityArgument.isEmpty()) { | 566 if (!qualityArgument.isEmpty()) { |
549 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 567 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
550 if (v8Value->IsNumber()) { | 568 if (v8Value->IsNumber()) { |
551 quality = v8Value.As<v8::Number>()->Value(); | 569 quality = v8Value.As<v8::Number>()->Value(); |
552 } | 570 } |
553 } | 571 } |
554 | 572 |
555 String encodingMimeType = toEncodingMimeType(mimeType); | 573 String encodingMimeType = toEncodingMimeType(mimeType); |
556 | 574 |
557 ImageData* imageData = toImageData(BackBuffer); | 575 ImageData* imageData = toImageData(BackBuffer); |
558 // imageData unref its data, which we still keep alive for the async toBlob thread | 576 // imageData unref its data, which we still keep alive for the async toBlob thread |
559 ScopedDisposal<ImageData> disposer(imageData); | 577 ScopedDisposal<ImageData> disposer(imageData); |
560 // Add a ref to keep image data alive until completion of encoding | 578 // Add a ref to keep image data alive until completion of encoding |
561 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 579 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
562 | 580 |
563 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); | 581 RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::cre ate(imageDataRef.release(), encodingMimeType, imageData->size(), callback); |
564 if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType == DefaultMimeType)) { | 582 if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType == kDefaultMimeType)) { |
565 asyncCreatorRef->scheduleAsyncBlobCreation(true); | 583 asyncCreatorRef->scheduleAsyncBlobCreation(true); |
566 } else { | 584 } else { |
567 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); | 585 asyncCreatorRef->scheduleAsyncBlobCreation(false, quality); |
568 } | 586 } |
569 } | 587 } |
570 | 588 |
571 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 589 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
572 { | 590 { |
573 return document().securityOrigin(); | 591 return document().securityOrigin(); |
574 } | 592 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
609 return false; | 627 return false; |
610 } | 628 } |
611 | 629 |
612 // Do not use acceleration for small canvas. | 630 // Do not use acceleration for small canvas. |
613 if (canvasPixelCount < settings->minimumAccelerated2dCanvasSize()) | 631 if (canvasPixelCount < settings->minimumAccelerated2dCanvasSize()) |
614 return false; | 632 return false; |
615 | 633 |
616 if (!Platform::current()->canAccelerate2dCanvas()) | 634 if (!Platform::current()->canAccelerate2dCanvas()) |
617 return false; | 635 return false; |
618 | 636 |
637 // When GPU allocated memory runs low (due to having created too many accele rated canvases), the | |
638 // compositor starves and browser becomes laggy. Thus, we should stop alloca ting more GPU memory to | |
639 // new canvases created when the current memory usage exceeds the threshold. | |
640 if (s_totalMemoryForAcceleratedCanvases >= kMaxTotalExternallyAllocatedMemor y) | |
Justin Novosad
2015/12/02 16:33:34
Constant should be named in a way that reflects th
| |
641 return false; | |
642 | |
619 return true; | 643 return true; |
620 } | 644 } |
621 | 645 |
622 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa ctory { | 646 class UnacceleratedSurfaceFactory : public RecordingImageBufferFallbackSurfaceFa ctory { |
623 public: | 647 public: |
624 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op acityMode opacityMode) | 648 virtual PassOwnPtr<ImageBufferSurface> createSurface(const IntSize& size, Op acityMode opacityMode) |
625 { | 649 { |
626 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); | 650 return adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); |
627 } | 651 } |
628 | 652 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
769 if (is3D()) | 793 if (is3D()) |
770 checkedExternallyAllocatedMemory += m_context->externallyAllocatedBytesP erPixel(); | 794 checkedExternallyAllocatedMemory += m_context->externallyAllocatedBytesP erPixel(); |
771 | 795 |
772 checkedExternallyAllocatedMemory *= width(); | 796 checkedExternallyAllocatedMemory *= width(); |
773 checkedExternallyAllocatedMemory *= height(); | 797 checkedExternallyAllocatedMemory *= height(); |
774 intptr_t externallyAllocatedMemory; | 798 intptr_t externallyAllocatedMemory; |
775 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) | 799 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) |
776 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); | 800 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); |
777 | 801 |
778 // Subtracting two intptr_t that are known to be positive will never underfl ow. | 802 // Subtracting two intptr_t that are known to be positive will never underfl ow. |
779 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyA llocatedMemory - m_externallyAllocatedMemory); | 803 intptr_t diffFromCurrAllocatedMemory = externallyAllocatedMemory - m_externa llyAllocatedMemory; |
804 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diffFromCur rAllocatedMemory); | |
780 m_externallyAllocatedMemory = externallyAllocatedMemory; | 805 m_externallyAllocatedMemory = externallyAllocatedMemory; |
806 | |
807 if (m_imageBuffer && m_imageBuffer->isAccelerated()) | |
808 updateTotalMemoryForAcceleratedCanvases(diffFromCurrAllocatedMemory); | |
Justin Novosad
2015/12/02 16:33:34
This is wrong. You need to track gpu allocated mem
| |
809 } | |
810 | |
811 void HTMLCanvasElement::updateTotalMemoryForAcceleratedCanvases(intptr_t diffFro mCurrAllocatedMemory) | |
812 { | |
813 ASSERT(isMainThread()); | |
814 | |
815 Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = s_total MemoryForAcceleratedCanvases; | |
Justin Novosad
2015/12/02 16:33:33
Don't use the term "ExternallyAllocated" here, it
| |
816 checkedExternallyAllocatedMemory += diffFromCurrAllocatedMemory; | |
817 intptr_t externallyAllocatedMemory; | |
818 if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == C heckedState::DidOverflow) | |
819 externallyAllocatedMemory = std::numeric_limits<intptr_t>::max(); | |
820 | |
821 s_totalMemoryForAcceleratedCanvases = externallyAllocatedMemory; | |
781 } | 822 } |
782 | 823 |
783 SkCanvas* HTMLCanvasElement::drawingCanvas() const | 824 SkCanvas* HTMLCanvasElement::drawingCanvas() const |
784 { | 825 { |
785 return buffer() ? m_imageBuffer->canvas() : nullptr; | 826 return buffer() ? m_imageBuffer->canvas() : nullptr; |
786 } | 827 } |
787 | 828 |
788 void HTMLCanvasElement::disableDeferral() const | 829 void HTMLCanvasElement::disableDeferral() const |
789 { | 830 { |
790 if (buffer()) | 831 if (buffer()) |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
952 } | 993 } |
953 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr); | 994 return ImageBitmapSource::fulfillImageBitmap(scriptState, isPaintable() ? Im ageBitmap::create(this, IntRect(sx, sy, sw, sh)) : nullptr); |
954 } | 995 } |
955 | 996 |
956 bool HTMLCanvasElement::isOpaque() const | 997 bool HTMLCanvasElement::isOpaque() const |
957 { | 998 { |
958 return m_context && !m_context->hasAlpha(); | 999 return m_context && !m_context->hasAlpha(); |
959 } | 1000 } |
960 | 1001 |
961 } // blink | 1002 } // blink |
OLD | NEW |