Chromium Code Reviews| 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 |